1 题目
You have d
dice, and each die has f
faces numbered 1, 2, ..., f
.
Return the number of possible ways (out of fd
total ways) modulo 10^9 + 7
to roll the dice so the sum of the face up numbers equals target
.
Example 1:
Input: d = 1, f = 6, target = 3
Output: 1
Explanation:
You throw one die with 6 faces. There is only one way to get a sum of 3.
Example 2:
Input: d = 2, f = 6, target = 7
Output: 6
Explanation:
You throw two dice, each with 6 faces. There are 6 ways to get a sum of 7:
1+6, 2+5, 3+4, 4+3, 5+2, 6+1.
Example 3:
Input: d = 2, f = 5, target = 10
Output: 1
Explanation:
You throw two dice, each with 5 faces. There is only one way to get a sum of 10: 5+5.
Example 4:
Input: d = 1, f = 2, target = 3
Output: 0
Explanation:
You throw one die with 2 faces. There is no way to get a sum of 3.
Example 5:
Input: d = 30, f = 30, target = 500
Output: 222616187
Explanation:
The answer must be returned modulo 10^9 + 7.
2 尝试解
2.1 分析
有d个骰子,每个骰子有f个面,分别有数字1,2...f。问如果要使得所有骰子的数字之和为target,有多少种解法。
典型的动态规划题目,N(f,d,target) = sum (N(d-1,f,target-i) for i in range(1,f+1))。终止条件为 d == 0或者target <= 0,此时如果d==target,则返回1,否则返回0。
2.2 代码
class Solution {
public:
int numRollsToTarget(int d, int f, int target) {
map<pair<int,int>,long> record;
return help(d,f,target,record);
}
long help(int d,int&f,int target,map<pair<int,int>,long>&record){
pair<int,int> index{d,target};
if(record.count(index)!= 0) ;
else if(target <= 0 || d == 0)
record[index] = (d==target?1:0);
else{
record[index] = 0;
for(int i = 1; i <= f; i++){
record[index] = (record[index] + help(d-1,f,target-i,record))%1000000007;
}
}
return record[index];
}
};
3 标准解
3.1 分析
如果两个正六面体骰子要掷出11,即5+6&6+5,如果骰子相对两面之和为固定值,即1和6相对,2和5相对,那么该问题等同于掷出2+1&1+2。即如果target > (f+1)*d/2, target = (f+1)*d-target
3.2 代码
class Solution {
public:
int numRollsToTarget(int d, int f, int target) {
map<pair<int,int>,long> record;
return help(d,f,target,record);
}
long help(int d,int&f,int target,map<pair<int,int>,long>&record){
target = min(target, d*(f+1)-target);
pair<int,int> index{d,target};
if(record.count(index)!= 0) ;
else if(target <= 0 || d == 0)
record[index] = (d==target?1:0);
else{
record[index] = 0;
for(int i = 1; i <= f; i++){
record[index] = (record[index] + help(d-1,f,target-i,record))%1000000007;
}
}
return record[index];
}
};