题目描述:
把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能出现的值出现的概率。
解题思路:
- 将n个骰子分为两堆,第一堆只有一个,剩下一堆有n-1个
- 然后再计算n-1个骰子的点数之和,过程和第一步一致
- 这显然是一种递归的解法
- 总共n个骰子,有6~n种排列组合,骰子点数之和在n到6n之间,所以可以用一个5n+1的数组来存放出现点数之和的次数,将和为s的点数存放在数组的第s-n个元素里
考虑到递归解法,进行了很多重复的计算,所以可以考虑使用基于循环的方法
public static int max = 6; public static List<Map.Entry<Integer,Double>> printProbability(int number){ List<Map.Entry<Integer, Double>> ret = new ArrayList<Map.Entry<Integer,Double>>(); if(number<1) return ret; int maxSum = max*number; int[] a = new int[maxSum-number+1]; for(int i=number;i<=maxSum;i++) a[i-number] = 0; proba(number,a); double total = Math.pow(max, number); for(int i = number;i<=maxSum;i++){ double ratio = a[i-number]/total; ret.add(new AbstractMap.SimpleEntry<>(i,ratio)); } return ret; } public static void proba(int number,int[] a){ for(int i = 1;i<=max;i++) proba_ini(number,number,i,a); } public static void proba_ini(int original,int current,int sum,int[] a){ if(current==1) a[sum-original]++; else { for(int i =1;i<=max;i++) proba_ini(original, current-1, sum+i, a); } }后面考虑使用动态规划的解法