文章目录
思路
首先一一眼看就是一个动态规划问题;那就用dp做
有哪些变量呢,有:掷骰子的数目,达到target的种数,掷骰子的和,和每次掷骰子的数目。
1.确定dp数组如何确立:答案要求返回的是达到target的种数那么我们的这个dp数组代表的就是达到target的种数,还有现在在掷那个骰子和当前掷骰子的和需要表示,那么我们的dp数组就要这么设计:dp[当前在掷那个骰子][当前掷骰子的和]=达到这个和的种数;
2.确定答案要返回什么:要反返回掷完骰子达到的种数:也就是返回:return dp[n][target];
-
dp数组初始化:先归零memset(dp,0,sizeof(dp));然后确定初始值:dp[0][0]第0个骰子的种数肯定就是1了; dp[0][0]=1;
-
确定dp推导公式:我们dp代表的是数量,l代表当前骰子投的数的话就是当前dp[i][j]可以达到的种数加上投l的种数dp[i-1][j-l]的种数也就是: dp[i][j]=(dp[i][j]+dp[i-1][j-l]);
-
注意要MOD1e9+7
代码如下:
cpp
class Solution {
public:
int numRollsToTarget(int n, int k, int target) {
int dp[n+1][target+1];//dp结果为骰子种数;n为进行的第n个骰子,target为骰子的和
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i =1;i<=n;i++){
for(int j=1;j<=target;j++){
for(int l=1;l<=k;l++){
if(l<=j){
dp[i][j]=(dp[i][j]+dp[i-1][j-l])%(int)(1e9+7);
}
}
}
}
return dp[n][target];
}
};
题目如下:
这里有 n 个一样的骰子,每个骰子上都有 k 个面,分别标号为 1 到 k 。
给定三个整数 n , k 和 target ,返回可能的方式(从总共 kn 种方式中)滚动骰子的数量,使正面朝上的数字之和等于 target 。
答案可能很大,你需要对 109 + 7 取模 。
示例 1:
输入:n = 1, k = 6, target = 3
输出:1
解释:你扔一个有 6 个面的骰子。
得到 3 的和只有一种方法。
示例 2:
输入:n = 2, k = 6, target = 7
输出:6
解释:你扔两个骰子,每个骰子有 6 个面。
得到 7 的和有 6 种方法:1+6 2+5 3+4 4+3 5+2 6+1。
示例 3:
输入:n = 30, k = 30, target = 500
输出:222616187
解释:返回的结果必须是对 109 + 7 取模。
提示:
1 <= n, k <= 30
1 <= target <= 1000