Number of ways to get a given sum with n number of m-faced dices
Given n dices, each with m faces, numbered from 1 to m, find the number of ways to get a given sum X. X is the summation of values on each face when all the dice are thrown.
Examples:
Input : faces = 4 throws = 2 sum =4
Output : 3
Ways to reach sum equal to 4 in 2 throws can be { (1, 3), (2, 2), (3, 1) }
Input : faces = 6 throws = 3 sum = 12
Output : 25
Approach:
Basically, it is asked to achieve sum in n number of operations using the values in the range [1…m].
Use dynamic programming top-down methodology for this problem. The steps are:
- Base Cases:
- If (sum == 0 and noofthrowsleft ==0) return 1 . It means that sum x has
been achieved.
- If (sum < 0 and noofthrowsleft ==0) return 0.It means that sum x has not
been achieved in all throws.
- If present sum with present noofthrowsleft is already achieved then return it from the table instead of re computation.
- Then we will loop through all the values of faces from i=[1..m] and recursively moving to achieve sum-i and also decrease the noofthrowsleft by 1.
- Finally, we will store current values in the dp array
Below is the implementation of the above method:
C++
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
int dp[55][55];
int NoofWays( int face, int throws, int sum)
{
if (sum == 0 && throws == 0)
return 1;
if (sum < 0 || throws == 0)
return 0;
if (dp[throws][sum] != -1)
return dp[throws][sum];
int ans = 0;
for ( int i = 1; i <= face; i++) {
ans += NoofWays(face, throws - 1, sum - i);
}
return dp[throws][sum] = ans;
}
int main()
{
int faces = 6, throws = 3, sum = 12;
memset (dp, -1, sizeof dp);
cout << NoofWays(faces, throws, sum) << endl;
return 0;
}
|
Java
class GFG
{
static int mod = 1000000007 ;
static int [][] dp = new int [ 55 ][ 55 ];
static int NoofWays( int face, int throwsVal, int sum)
{
if (sum == 0 && throwsVal == 0 )
{
return 1 ;
}
if (sum < 0 || throwsVal == 0 )
{
return 0 ;
}
if (dp[throwsVal][sum] != - 1 )
{
return dp[throwsVal][sum];
}
int ans = 0 ;
for ( int i = 1 ; i <= face; i++)
{
ans += NoofWays(face, throwsVal - 1 , sum - i);
}
return dp[throwsVal][sum] = ans;
}
public static void main(String[] args)
{
int faces = 6 , throwsVal = 3 , sum = 12 ;
for ( int i = 0 ; i < 55 ; i++)
{
for ( int j = 0 ; j < 55 ; j++)
{
dp[i][j] = - 1 ;
}
}
System.out.println(NoofWays(faces, throwsVal, sum));
}
}
|
Python3
import numpy as np
mod = 1000000007 ;
dp = np.zeros(( 55 , 55 ));
def NoofWays(face, throws, sum ) :
if ( sum = = 0 and throws = = 0 ) :
return 1 ;
if ( sum < 0 or throws = = 0 ) :
return 0 ;
if (dp[throws][ sum ] ! = - 1 ) :
return dp[throws][ sum ];
ans = 0 ;
for i in range ( 1 , face + 1 ) :
ans + = NoofWays(face, throws - 1 , sum - i);
dp[throws][ sum ] = ans;
return ans;
if __name__ = = "__main__" :
faces = 6 ; throws = 3 ; sum = 12 ;
for i in range ( 55 ) :
for j in range ( 55 ) :
dp[i][j] = - 1
print (NoofWays(faces, throws, sum )) ;
|
C#
using System;
class GFG
{
static int [,]dp = new int [55,55];
static int NoofWays( int face, int throwsVal, int sum)
{
if (sum == 0 && throwsVal == 0)
{
return 1;
}
if (sum < 0 || throwsVal == 0)
{
return 0;
}
if (dp[throwsVal,sum] != -1)
{
return dp[throwsVal,sum];
}
int ans = 0;
for ( int i = 1; i <= face; i++)
{
ans += NoofWays(face, throwsVal - 1, sum - i);
}
return dp[throwsVal,sum] = ans;
}
static public void Main ()
{
int faces = 6, throwsVal = 3, sum = 12;
for ( int i = 0; i < 55; i++)
{
for ( int j = 0; j < 55; j++)
{
dp[i,j] = -1;
}
}
Console.WriteLine(NoofWays(faces, throwsVal, sum));
}
}
|
Javascript
<script>
const mod = 1000000007;
let dp = new Array(55);
for (let i = 0; i < 55; i++)
dp[i] = new Array(55).fill(-1);
function NoofWays(face, throws, sum)
{
if (sum == 0 && throws == 0)
return 1;
if (sum < 0 || throws == 0)
return 0;
if (dp[throws][sum] != -1)
return dp[throws][sum];
let ans = 0;
for (let i = 1; i <= face; i++) {
ans += NoofWays(face, throws - 1, sum - i);
}
return dp[throws][sum] = ans;
}
let faces = 6, throws = 3, sum = 12;
document.write(NoofWays(faces, throws, sum));
</script>
|
Time complexity : O(throws*faces*sum)
Space complexity : O(faces*sum)
Efficient approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.
Steps to solve this problem :
- Create a 2D array DP to store the solution of the subproblems and initialize it with 0.
- Initialize the DP with base cases.
- Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP.
- Return the final solution stored in dp[throws][sum] .
Implementation :
C++
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
int dp[55][55];
int NoofWays( int face, int throws, int sum)
{
memset (dp, 0, sizeof dp);
for ( int i = 1; i <= face && i <= sum; i++)
dp[1][i] = 1;
for ( int t = 2; t <= throws; t++)
{
for ( int s = 1; s <= sum; s++)
{
for ( int i = 1; i <= face && i < s; i++)
{
dp[t][s] += dp[t - 1][s - i];
dp[t][s] %= mod;
}
}
}
return dp[throws][sum];
}
int main()
{
int faces = 6, throws = 3, sum = 12;
cout << NoofWays(faces, throws, sum) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
static int mod = 1000000007 ;
static int [][] dp = new int [ 55 ][ 55 ];
static int NoofWays( int face, int throws_, int sum)
{
Arrays.stream(dp).forEach(a -> Arrays.fill(a, 0 ));
for ( int i = 1 ; i <= face && i <= sum; i++)
dp[ 1 ][i] = 1 ;
for ( int t = 2 ; t <= throws_; t++) {
for ( int s = 1 ; s <= sum; s++) {
for ( int i = 1 ; i <= face && i < s; i++) {
dp[t][s] += dp[t - 1 ][s - i];
dp[t][s] %= mod;
}
}
}
return dp[throws_][sum];
}
public static void main(String[] args)
{
int faces = 6 , throws_ = 3 , sum = 12 ;
System.out.println(NoofWays(faces, throws_, sum));
}
}
|
Python3
mod = 1000000007
def NoofWays(face, throws, sum ):
dp = [[ 0 for i in range ( sum + 1 )] for j in range (throws + 1 )]
for i in range ( 1 , face + 1 ):
if i < = sum :
dp[ 1 ][i] = 1
for t in range ( 2 , throws + 1 ):
for s in range ( 1 , sum + 1 ):
for i in range ( 1 , face + 1 ):
if i < s:
dp[t][s] + = dp[t - 1 ][s - i]
dp[t][s] % = mod
return dp[throws][ sum ]
faces = 6
throws = 3
sum = 12
print (NoofWays(faces, throws, sum ))
|
C#
using System;
class MainClass {
public static int NoofWays( int face, int throws, int sum)
{
int [, ] dp = new int [55, 55];
for ( int i = 1; i <= face && i <= sum; i++)
dp[1, i] = 1;
for ( int t = 2; t <= throws; t++) {
for ( int s = 1; s <= sum; s++) {
for ( int i = 1; i <= face && i < s; i++) {
dp[t, s] += dp[t - 1, s - i];
dp[t, s] %= 1000000007;
}
}
}
return dp[throws, sum];
}
public static void Main( string [] args)
{
int faces = 6, throws = 3, sum = 12;
Console.WriteLine(NoofWays(faces, throws, sum));
}
}
|
Javascript
function NoofWays(face, throws, sum) {
const mod = 1000000007;
const dp = new Array(55).fill().map(() => new Array(55).fill(0));
for (let i = 1; i <= face && i <= sum; i++) {
dp[1][i] = 1;
}
for (let t = 2; t <= throws; t++) {
for (let s = 1; s <= sum; s++) {
for (let i = 1; i <= face && i < s; i++) {
dp[t][s] += dp[t - 1][s - i];
dp[t][s] %= mod;
}
}
}
return dp[throws][sum];
}
const faces = 6;
const throws = 3;
const sum = 12;
console.log(NoofWays(faces, throws, sum));
|
Output
25
Time complexity : O(throws*faces*sum)
Auxiliary Space : O(throws*sum)
Last Updated :
19 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...