Count ways to obtain given sum by repeated throws of a dice
Given an integer N, the task is to find the number of ways to get the sum N by repeatedly throwing a dice.
Examples:
Input: N = 3
Output: 4
Explanation:
The four possible ways to obtain N are:
Input: N = 2
Output: 2
Explanation:
The two possible ways to obtain N are:
Recursive Approach: The idea is to iterate for every possible value of dice to get the required sum N. Below are the steps:
- Let findWays() be the required answer for sum N.
- The only numbers obtained from the throw of dice are [1, 6], each having equal probability in a single throw of dice.
- Therefore, for every state, recur for the previous (N – i) states (where 1 ? i ? 6). Therefore, the recursive relation is as follows:
findWays(N) = findWays(N – 1) + findWays(N – 2) + findWays(N – 3) + findWays(N – 4) + findWays(N – 5) + findWays(N – 6)
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findWays( int N)
{
if (N == 0) {
return 1;
}
int cnt = 0;
for ( int i = 1; i <= 6; i++) {
if (N - i >= 0) {
cnt = cnt
+ findWays(N - i);
}
}
return cnt;
}
int main()
{
int N = 4;
cout << findWays(N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int findWays( int N)
{
if (N == 0 )
{
return 1 ;
}
int cnt = 0 ;
for ( int i = 1 ; i <= 6 ; i++)
{
if (N - i >= 0 )
{
cnt = cnt +
findWays(N - i);
}
}
return cnt;
}
public static void main(String[] args)
{
int N = 4 ;
System.out.print(findWays(N));
}
}
|
Python3
def findWays(N):
if (N = = 0 ):
return 1
cnt = 0
for i in range ( 1 , 7 ):
if (N - i > = 0 ):
cnt = cnt + findWays(N - i)
return cnt
if __name__ = = '__main__' :
N = 4
print (findWays(N))
|
C#
using System;
class GFG{
static int findWays( int N)
{
if (N == 0)
{
return 1;
}
int cnt = 0;
for ( int i = 1; i <= 6; i++)
{
if (N - i >= 0)
{
cnt = cnt + findWays(N - i);
}
}
return cnt;
}
public static void Main()
{
int N = 4;
Console.Write(findWays(N));
}
}
|
Javascript
<script>
function findWays(N)
{
if (N == 0) {
return 1;
}
var cnt = 0;
for ( var i = 1; i <= 6; i++) {
if (N - i >= 0) {
cnt = cnt
+ findWays(N - i);
}
}
return cnt;
}
var N = 4;
document.write( findWays(N));
</script>
|
Time Complexity: O(6N)
Auxiliary Space: O(1)
Dynamic Programming Approach: The above recursive approach needs to be optimized by dealing with the following overlapping subproblems:
Overlapping Subproblems:
Partial recursion tree for N = 8:
Optimal Substructure: As for every state, recurrence occurs for 6 states, so the recursive definition of dp(N) is the following:
dp[N] = dp[N-1] + dp[N-2] + dp[N-3] + dp[N-4] + dp[N-5] + dp[N-6]
Follow the steps below to solve the problem:
- Initialize an auxiliary array dp[] of size N + 1 with initial value -1, where dp[i] stores the count of ways of having sum i.
- The base case while solving this problem is if N is equal to 0 in any state, the result to such a state is 1.
- If for any state dp[i] is not equal to -1, then this value as this substructure is already beed calculated.
Top-Down Approach: Below is the implementation of the Top-Down approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findWays( int N, int dp[])
{
if (N == 0) {
return 1;
}
if (dp[N] != -1) {
return dp[N];
}
int cnt = 0;
for ( int i = 1; i <= 6; i++) {
if (N - i >= 0) {
cnt = cnt
+ findWays(N - i, dp);
}
}
return dp[N] = cnt;
}
int main()
{
int N = 4;
int dp[N + 1];
memset (dp, -1, sizeof (dp));
cout << findWays(N, dp);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int findWays( int N, int dp[])
{
if (N == 0 )
{
return 1 ;
}
if (dp[N] != - 1 )
{
return dp[N];
}
int cnt = 0 ;
for ( int i = 1 ; i <= 6 ; i++)
{
if (N - i >= 0 )
{
cnt = cnt +
findWays(N - i, dp);
}
}
return dp[N] = cnt;
}
public static void main(String[] args)
{
int N = 4 ;
int []dp = new int [N + 1 ];
for ( int i = 0 ; i < dp.length; i++)
dp[i] = - 1 ;
System.out.print(findWays(N, dp));
}
}
|
Python3
def findWays(N, dp):
if (N = = 0 ):
return 1
if (dp[N] ! = - 1 ):
return dp[N]
cnt = 0
for i in range ( 1 , 7 ):
if (N - i > = 0 ):
cnt = (cnt +
findWays(N - i, dp))
dp[N] = cnt
return dp[N]
if __name__ = = "__main__" :
N = 4
dp = [ - 1 ] * (N + 1 )
print (findWays(N, dp))
|
C#
using System;
class GFG{
static int findWays( int N, int []dp)
{
if (N == 0)
{
return 1;
}
if (dp[N] != -1)
{
return dp[N];
}
int cnt = 0;
for ( int i = 1; i <= 6; i++)
{
if (N - i >= 0)
{
cnt = cnt + findWays(N - i, dp);
}
}
return dp[N] = cnt;
}
public static void Main(String[] args)
{
int N = 4;
int []dp = new int [N + 1];
for ( int i = 0; i < dp.Length; i++)
dp[i] = -1;
Console.Write(findWays(N, dp));
}
}
|
Javascript
<script>
function findWays(N,dp)
{
if (N == 0)
{
return 1;
}
if (dp[N] != -1)
{
return dp[N];
}
let cnt = 0;
for (let i = 1; i <= 6; i++)
{
if (N - i >= 0)
{
cnt = cnt +
findWays(N - i, dp);
}
}
return dp[N] = cnt;
}
let N = 4;
let dp = new Array(N + 1);
for (let i = 0; i < dp.length; i++)
dp[i] = -1;
document.write(findWays(N, dp));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Bottom-Up Approach: Below is the implementation of the Bottom-up Dynamic Programming approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findWays( int N)
{
int dp[N + 1];
dp[0] = 1;
for ( int i = 1; i <= N; i++) {
dp[i] = 0;
for ( int j = 1; j <= 6; j++) {
if (i - j >= 0) {
dp[i] = dp[i] + dp[i - j];
}
}
}
cout << dp[N];
}
int main()
{
int N = 4;
findWays(N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static void findWays( int N)
{
int []dp = new int [N + 1 ];
dp[ 0 ] = 1 ;
for ( int i = 1 ; i <= N; i++)
{
dp[i] = 0 ;
for ( int j = 1 ; j <= 6 ; j++)
{
if (i - j >= 0 )
{
dp[i] = dp[i] + dp[i - j];
}
}
}
System.out.print(dp[N]);
}
public static void main(String[] args)
{
int N = 4 ;
findWays(N);
}
}
|
Python3
def findWays(N):
dp = [ 0 ] * (N + 1 );
dp[ 0 ] = 1 ;
for i in range ( 1 , N + 1 ):
dp[i] = 0 ;
for j in range ( 1 , 7 ):
if (i - j > = 0 ):
dp[i] = dp[i] + dp[i - j];
print (dp[N]);
if __name__ = = '__main__' :
N = 4 ;
findWays(N);
|
C#
using System;
class GFG{
static void findWays( int N)
{
int []dp = new int [N + 1];
dp[0] = 1;
for ( int i = 1; i <= N; i++)
{
dp[i] = 0;
for ( int j = 1; j <= 6; j++)
{
if (i - j >= 0)
{
dp[i] = dp[i] + dp[i - j];
}
}
}
Console.Write(dp[N]);
}
public static void Main(String[] args)
{
int N = 4;
findWays(N);
}
}
|
Javascript
<script>
function findWays(N)
{
let dp = new Array(N + 1);
dp[0] = 1;
for (let i = 1; i <= N; i++)
{
dp[i] = 0;
for (let j = 1; j <= 6; j++)
{
if (i - j >= 0)
{
dp[i] = dp[i] + dp[i - j];
}
}
}
document.write(dp[N]);
}
let N = 4;
findWays(N);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Efficient Approach: space optimization O(1)
To optimize the space complexity of the previous solution by using only an array of size 6 instead of an array of size N+1 to store the values of dp. We only need to store the values for the last 6 values of dp at any point in time.
Implementation Steps:
- Create an array DP if size 6 instead of size N because we need only the previous 6 computations to get the current value.
- Initialize DP with base case dp[0] = 1.
- Iterate over subproblems and get the current value from previous solutions of subproblems stored in DP.
- At the last return, the final answer is stored in dp[N%6]. ( n%6 ) to compute only the last 6 values.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
void findWays( int N)
{
int dp[6];
dp[0] = 1;
for ( int i = 1; i <= N; i++) {
int sum = 0;
for ( int j = 1; j <= 6; j++) {
if (i - j >= 0) {
sum += dp[(i-j)%6];
}
}
dp[i%6] = sum;
}
cout << dp[N%6];
}
int main()
{
int N = 4;
findWays(N);
return 0;
}
|
Java
import java.util.*;
public class DiceSum {
public static void findWays( int N) {
int [] dp = new int [ 6 ];
dp[ 0 ] = 1 ;
for ( int i = 1 ; i <= N; i++) {
int sum = 0 ;
for ( int j = 1 ; j <= 6 ; j++) {
if (i - j >= 0 ) {
sum += dp[(i-j)% 6 ];
}
}
dp[i% 6 ] = sum;
}
System.out.println(dp[N% 6 ]);
}
public static void main(String[] args) {
int N = 4 ;
findWays(N);
}
}
|
Python3
def findWays(N):
dp = [ 0 ] * 6
dp[ 0 ] = 1
for i in range ( 1 , N + 1 ):
sum = 0
for j in range ( 1 , 7 ):
if i - j > = 0 :
sum + = dp[(i - j) % 6 ]
dp[i % 6 ] = sum
print (dp[N % 6 ])
if __name__ = = '__main__' :
N = 4
findWays(N)
|
C#
using System;
public class MainClass
{
public static void Main()
{
int N = 4;
int [] dp = new int [6];
dp[0] = 1;
for ( int i = 1; i <= N; i++)
{
int sum = 0;
for ( int j = 1; j <= 6; j++)
{
if (i - j >= 0)
{
sum += dp[(i-j)%6];
}
}
dp[i%6] = sum;
}
Console.WriteLine(dp[N%6]);
}
}
|
Javascript
let N = 4;
let dp = new Array(6).fill(0);
dp[0] = 1;
for (let i = 1; i <= N; i++) {
let sum = 0;
for (let j = 1; j <= 6; j++) {
if (i - j >= 0) {
sum += dp[(i - j) % 6];
}
}
dp[i % 6] = sum;
}
console.log(dp[N % 6]);
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Last Updated :
09 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...