难度:中等。
动态规划,使用
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示使用i个骰子掷出和为j的情况的个数。则
d
p
[
i
]
[
j
]
=
∑
k
=
1
6
d
p
[
i
−
1
]
[
j
−
k
]
dp[i][j]= \sum_{k=1}^6dp[i - 1][j - k]
dp[i][j]=∑k=16dp[i−1][j−k]
正确解法:
class Solution {
public:
vector<double> dicesProbability(int n) {
vector<vector<int>> dp(n + 1, vector<int>(n * 6 + 1));
for(int i = 1; i <= 6; ++i){
dp[1][i] = 1;
}
for(int i = 2; i <= n; ++i){
for(int j = i; j <= i * 6; ++j){
for(int k = 1; k <= 6; ++k){
if(j - k >= i - 1){
dp[i][j] += dp[i - 1][j - k];
}
}
}
}
vector<double> res;
int sum = pow(6, n);
for(int i = n; i <= n * 6; ++i){
res.emplace_back(double(dp[n][i]) / sum);
}
return res;
}
};
结果:
优化,每个阶段都只与其前一阶段有关,即 d p [ i ] [ ] dp[i][] dp[i][]只与 d p [ i − 1 ] [ ] dp[i-1][] dp[i−1][]有关,因此可以对内存进行优化。
正确解法:
class Solution {
public:
vector<double> dicesProbability(int n) {
vector<int> dp(n * 6 + 1);
for(int i = 1; i <= 6; ++i){
dp[i] = 1;
}
for(int i = 2; i <= n; ++i){
for(int j = i * 6; j >= i; --j){
dp[j] = 0;
for(int k = 1; k <= 6; ++k){
if(j - k >= i - 1){
dp[j] += dp[j - k];
}
}
}
}
vector<double> res;
int sum = pow(6, n);
for(int i = n; i <= n * 6; ++i){
res.emplace_back(double(dp[i]) / sum);
}
return res;
}
};
结果: