题目描述:
扔 n 个骰子,向上面的数字之和为 S。给定 n,请列出所有可能的 S 值及其相应的概率。
样例:
给定 n = 1
,返回 [ [1, 0.17], [2, 0.17], [3, 0.17], [4, 0.17], [5, 0.17], [6, 0.17]]
。
分析:
参考了一篇很好的博客:https://www.cnblogs.com/bozhou/p/6971081.html
题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S的所有可能的值出现的概率。
1.假设在n个骰子和点数和Sum的情况下,次数m = f(n,Sum)
2.当然n-1块骰子的情况下,一般情况下可投出Sum-1、Sum-2、Sum-3、Sum-4、Sum-5、Sum-6的情况,即留给最后一块骰子1-6的投掷空间;
(k-1,n-1):第k个骰子投了点数1
(k-1,n-2):第k个骰子投了点数2
(k-1,n-3):第k个骰子投了点数3
....
(k-1,n-6):第k个骰子投了点数6
AllPro = f(n,Sum) = f(n-1,Sum-1) + f(n-1,Sum-2) + f(n-1,Sum-3) + f(n-1,Sum-4) + f(n-1,Sum-5) + f(n-1,Sum-6)
3.特殊情况一,Sum - i < 1 *(n-1),即留给n-1块骰子的投掷空间已经比n-1块骰子的最小点数和还小了!
AllPro = f(n,Sum) = f(n-1,Sum-i) + f(n-1,Sum-i-1) + ... + f(n-1,Sum-5) + f(n-1,Sum-6)
4.特殊情况二,Sum - i > 6 *(n-1),即留给n-1块骰子的投掷空间已经比n-1块骰子的最大点数和还大了!
AllPro = f(n,Sum) = f(n-1,Sum-1) + f(n-1,Sum-2) + ... + f(n-1,Sum-i) + f(n-1,Sum-i-1)
例如 n = 1时:
f(1,1) = f(1,2) = f(1,3) = f(1,4) = f(1,5) = f(1,6) = 1
而 n = 2时:
f(2,2) = f(1,1) = 1
f(2,3) = f(1,2) + f(1,1) = 2
...
f(2,6) = f(1,5) + f(1,4) + f(1,3) + f(1,2) + f(1,1)
f(2,7) = f(1,6) + f(1,5) + f(1,4) + f(1,3) + f(1,2) + f(1,1) = 6
f(2,8) = f(1,6) + f(1,5) + f(1,4) + f(1,3) + f(1,2) = 5
...
此时 f(2,2) 、f(2,3) ... f(2,6)就满足特殊情况一,而 f(2,8) 、f(2,9) ... f(2,12)就满足特殊情况二
public class Solution {
/**
* @param n an integer
* @return a list of Map.Entry<sum, probability>
*/
private TreeMap<Integer, Double> helper(TreeMap<Integer, Double> M){
TreeMap<Integer, Double> newM = new TreeMap<>();
double p = 1d/6;
for(int i = 1; i <= 6; i++)
for(int num : M.keySet()){
int key = num + i;
if(newM.containsKey(key)) newM.put(key, newM.get(key) + M.get(num)*p);
else newM.put(key, M.get(num)*(1d/6));
}
return newM;
}
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
TreeMap<Integer, Double> M = new TreeMap<>();
double p = 1d/6;
for(int i = 1; i <= 6; i++) M.put(i, p);
for(int i = 2; i <= n; i++) M = helper(M);
List<Map.Entry<Integer, Double>> ans = new ArrayList<>();
for(Map.Entry<Integer, Double> e : M.entrySet()) ans.add(e);
return ans;
}
}