描述
扔 n 个骰子,向上面的数字之和为 S。给定 Given n,请列出所有可能的 S 值及其相应的概率。
注意事项
You do not care about the accuracy of the result, we will help you to output results.
样例
给定 n = 1,返回 [ [1, 0.17], [2, 0.17], [3, 0.17], [4, 0.17], [5, 0.17], [6, 0.17]]。
代码
典型的动态规划题。定义一个二维数组,行代表骰子数,列代表总和,值代表当前扔了n个骰子的情况下,总和为某个值的可能数。假设当前有n个骰子,总和为sum的可能数为n-1个骰子,总和为sum-1,sum-2,sum-3,sum-4,sum-5,sum-6的可能数的加和。
注意一点是,n的值可以很大,因此,二维数组值的类型为long。
public class Solution {
/**
* @param n an integer
* @return a list of Map.Entry<sum, probability>
*/
public List<Map.Entry<Integer, Double>> dicesSum(int n) {
// Write your code here
// Ps. new AbstractMap.SimpleEntry<Integer, Double>(sum, pro)
// to create the pair
long[][] dp=new long[n+1][n*6+1];
List<Map.Entry<Integer, Double>> result=new ArrayList<>();
for(int i=1;i<=6;i++){
dp[1][i]=1;
}
double pro=Math.pow(6, n);
for(int i=2;i<=n;i++){
for(int j=i;j<=6*n;j++){
dp[i][j]=0;
int k;
if(j<=6){ //骰子的点数最大为6,因此循环的起点需要判断
k=1;
}else{
k=j-6;
}
for(;k<j;k++){
dp[i][j]+=dp[i-1][k];
}
}
}
for(int i=n;i<=6*n;i++){
result.add(new AbstractMap.SimpleEntry<Integer, Double>(i, (double)dp[n][i]/pro));
}
return result;
}
}