题目描述:
Throw n dices, the sum of the dices' faces is S. Given n, find the all possible value of Salong with its probability.
Given n = 1
, return[ [1, 0.17], [2, 0.17], [3, 0.17], [4, 0.17], [5, 0.17], [6, 0.17]]
.
这题用dfs做感觉更加直观,但是过不了time cost。换成dp的方法我是这么想的:
用dp[i][j]表示有i + 1个骰子的情况下,掷到的和为j的次数。那么intialize这个dp[0][j], j = 1...6的值都为1,然后从i = 1开始做循环。i个骰子和i + 1个骰子的差别就是1个骰子(废话),所以再用一个k = 1...6进行遍历,那么i + 1个骰子掷到j + k的次数就是原来dp[i][j + k]的次数加上dp[i - 1][j]。
这样我们就求得了n个骰子的情况下,每个S出现的次数dp[n - 1][j], j = n...6 * n。那么概率就是每个dp[n - 1][j]除以出现的总次数sum(dp[n - 1][j]).
这里要注意dp的值可能很大,所以要用到long long,否则在有些test case(e.g., n = 15)的情况下,会出现负数答案。
Mycode(AC = 12ms):
class Solution {
public:
/**
* @param n an integer
* @return a list of pair<sum, probability>
*/
vector<pair<int, double>> dicesSum(int n) {
vector<pair<int, double>> ans;
vector<vector<long long>> dp(n, vector<long long>(n * 6 + 1, 0));
// initialize the dp for n == 1
for (int i = 1; i <= 6; i++) {
dp[0][i] = 1;
}
// for each dp[i][j + k], it is equal to the
// number from dp[i - 1][j] + old dp[i][j + k]
for (int i = 1; i < n; i++) {
for (int j = i; j < i * 6 + 1; j++) {
for (int k = 1; k <= 6; k++) {
dp[i][j + k] += dp[i - 1][j];
}
}
}
// get the total count of number occurs
long long total_count = 0;
for (int i = n; i < n * 6 + 1; i++) {
if (dp[n - 1][i] > 0) {
total_count += dp[n - 1][i];
}
}
// get the probability
for (int i = 1; i < n * 6 + 1; i++) {
if (dp[n - 1][i] > 0) {
pair<int, double> p(i, (double)dp[n - 1][i]/(double)total_count);
ans.push_back(p);
}
}
return ans;
}
/*
vector<pair<int, double>> dicesSum(int n) {
// Write your code here
vector<pair<int, double>> ans;
vector<double> counter(n * 6 + 1, 0.0);
dicesSumHelper(counter, n, 0);
int total_count = 0;
for (int i = 1; i < counter.size(); i++) {
if (counter[i] > 0.0) {
total_count += counter[i];
}
}
for (int i = 1; i < counter.size(); i++) {
if (counter[i] > 0.0) {
pair<int, double> p(i, counter[i]/total_count);
ans.push_back(p);
}
}
return ans;
}
void dicesSumHelper(vector<double>& counter, int n, int sum) {
if (n < 0) return;
else if (n == 0) {
counter[sum] += 1.0;
return;
} else {
for (int i = 1; i <= 6; i++) {
dicesSumHelper(counter, n - 1, sum + i);
}
return;
}
}
*/
};