2022-7-13 剑指offer-数学-动态规划
剑指 Offer 60. n个骰子的点数
难度中等
把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。
你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。
1 class Solution { 2 public double[] dicesProbability(int n) { 3 int[][] f=new int[n+1][n*6+1]; 4 for (int i=1;i<=n;i++){ 5 for (int j=1;j<=n*6;j++){ 6 if (j>=i&&j<=6*i){ 7 if (i==1) f[i][j]=1; 8 else{ 9 for (int k=Math.max(i-1,j-6);k<=j-1;k++){ 10 f[i][j]+=f[i-1][k]; 11 } 12 } 13 } 14 } 15 } 16 double[] ans=new double[5*n+1]; 17 double x=1.0/6; 18 for (int i=0;i<5*n+1;i++){ 19 ans[i]=f[n][i+n]*Math.pow(x,n); 20 } 21 return ans; 22 } 23 }
思路:对于点数y的概率为(1/6)^n *f(x1+x2+x3+...+xn=y),f为满足括号内条件的数量。记为f(n,y),其含义为n个骰子投出y的组合数量,
f(n,y)=f(n-1,y-1)+f(n-1,y-2)+f(n-1,y-3)+f(n-1,y-4)+f(n-1,y-5)+f(n-1,y-6) 在合法的情况下。对于i个筛子,点数一定是i~6*i 之间,而递推公式中y-k必须保证大于等于筛子数量才有意义。