给定 n 个骰子,每个骰子有 m 个面,编号从 1 到 m,求获得给定总和 X 的方法数。X 是当所有骰子都掷出时每个面的值的总和。
例子:
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
方法:
基本上,要求使用范围 [1…m] 中的值在 n 次操作中求和。
对这个问题使用动态规划自顶向下的方法。步骤是:
- 基本案例:
- 如果 (sum == 0 and noofthrowsleft ==0) 返回 1 。这意味着总和 x 有
达到了。 - If (sum < 0 and noofthrowsleft ==0) return 0 。这意味着 sum x 没有
在所有投掷中都实现了。
- 如果 (sum == 0 and noofthrowsleft ==0) 返回 1 。这意味着总和 x 有
- 如果已经实现了当前 noofthrowsleft 的当前总和,则从表中返回它而不是重新计算。
- 然后我们将遍历 i=[1..m] 中的所有面值并递归移动以实现 sum-i 并将 noofthrowsleft 减少 1。
- 最后,我们将当前值存储在 dp 数组中
下面是上述方法的实现:
C++
// C++ function to calculate the number of
// ways to achieve sum x in n no of throws
#include
using namespace std;
#define mod 1000000007
int dp[55][55];
// Function to calculate recursively the
// number of ways to get sum in given
// throws and [1..m] values
int NoofWays(int face, int throws, int sum)
{
// Base condition 1
if (sum == 0 && throws == 0)
return 1;
// Base condition 2
if (sum < 0 || throws == 0)
return 0;
// If value already calculated dont
// move into re-computation
if (dp[throws][sum] != -1)
return dp[throws][sum];
int ans = 0;
for (int i = 1; i <= face; i++) {
// Recursively moving for sum-i in
// throws-1 no of throws left
ans += NoofWays(face, throws - 1, sum - i);
}
// Inserting present values in dp
return dp[throws][sum] = ans;
}
// Driver function
int main()
{
int faces = 6, throws = 3, sum = 12;
memset(dp, -1, sizeof dp);
cout << NoofWays(faces, throws, sum) << endl;
return 0;
}
Java
// Java function to calculate the number of
// ways to achieve sum x in n no of throwsVal
class GFG
{
static int mod = 1000000007;
static int[][] dp = new int[55][55];
// Function to calculate recursively the
// number of ways to get sum in given
// throwsVal and [1..m] values
static int NoofWays(int face, int throwsVal, int sum)
{
// Base condition 1
if (sum == 0 && throwsVal == 0)
{
return 1;
}
// Base condition 2
if (sum < 0 || throwsVal == 0)
{
return 0;
}
// If value already calculated dont
// move into re-computation
if (dp[throwsVal][sum] != -1)
{
return dp[throwsVal][sum];
}
int ans = 0;
for (int i = 1; i <= face; i++)
{
// Recursively moving for sum-i in
// throwsVal-1 no of throwsVal left
ans += NoofWays(face, throwsVal - 1, sum - i);
}
// Inserting present values in dp
return dp[throwsVal][sum] = ans;
}
// Driver code
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));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 function to calculate the number of
# ways to achieve sum x in n no of throws
import numpy as np
mod = 1000000007;
dp = np.zeros((55,55));
# Function to calculate recursively the
# number of ways to get sum in given
# throws and [1..m] values
def NoofWays(face, throws, sum) :
# Base condition 1
if (sum == 0 and throws == 0) :
return 1;
# Base condition 2
if (sum < 0 or throws == 0) :
return 0;
# If value already calculated dont
# move into re-computation
if (dp[throws][sum] != -1) :
return dp[throws][sum];
ans = 0;
for i in range(1, face + 1) :
# Recursively moving for sum-i in
# throws-1 no of throws left
ans += NoofWays(face, throws - 1, sum - i);
# Inserting present values in dp
dp[throws][sum] = ans;
return ans;
# Driver function
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)) ;
# This code is contributed by AnkitRai01
C#
// C# function to calculate the number of
// ways to achieve sum x in n no of throwsVal
using System;
class GFG
{
static int[,]dp = new int[55,55];
// Function to calculate recursively the
// number of ways to get sum in given
// throwsVal and [1..m] values
static int NoofWays(int face, int throwsVal, int sum)
{
// Base condition 1
if (sum == 0 && throwsVal == 0)
{
return 1;
}
// Base condition 2
if (sum < 0 || throwsVal == 0)
{
return 0;
}
// If value already calculated dont
// move into re-computation
if (dp[throwsVal,sum] != -1)
{
return dp[throwsVal,sum];
}
int ans = 0;
for (int i = 1; i <= face; i++)
{
// Recursively moving for sum-i in
// throwsVal-1 no of throwsVal left
ans += NoofWays(face, throwsVal - 1, sum - i);
}
// Inserting present values in dp
return dp[throwsVal,sum] = ans;
}
// Driver code
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));
}
}
// This code is contributed by ajit.
Javascript
输出:
25
时间复杂度: O(throws*faces*sum)
空间复杂度: O(faces*sum)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。