美文网首页
n个骰子的点数和为s的概率集合输出(Java)

n个骰子的点数和为s的概率集合输出(Java)

作者: dreamsfuture | 来源:发表于2018-03-16 08:47 被阅读0次

    问题描述:

    把n个骰子仍在地上,所有骰子朝上一面的点数之和为s,输入n,打印出s的所有可能出现的概率

    问题分析:

    这是一道应用动态规划思想的题目,而动态规划最难的就是要找最优子结构。并采取一种称为备忘录的方法避免重复计算。因为备忘录方法为每个解过的子问题建立了备忘录,以备需要时参看,避免了相同子问题的重复求解。

    最优子结构:

    F(n, s) 表示n个骰子点数和为s的种数,n表示骰子个数,s表示n个骰子的点数和
    F(n, s) = F(n-1, s-1) + F(n-1, s-2) + F(n-1, s-3) + F(n-1, s-4) + F(n-1, s-5) + F(n-1, s-6)

    public class Probability {  
    
        public void printProbability(int number) {  //number为骰子的个数
            if (number < 1)  return;  
    
            int g_maxValue = 6;    //骰子的最大点数为6
    
            int[][] probabilities = new int[2][];   //定义两个数组用于保存前一循环的数据供下一阶段使用
            probabilities[0] = new int[g_maxValue * number + 1];  
            probabilities[1] = new int[g_maxValue * number + 1];  
    
            int flag = 0;    //用于表示轮数交换的表示,当前阶段的信息做下一阶段的输入,上一阶段的信息清空,表示下阶段的输出
            //初始化骰子为1时,F(1,s) 的频数
            for (int i = 1; i <= g_maxValue; i++)  
                probabilities[0][i] = 1;  
    
            // n表示s要加上第n个骰子朝上的数,也表示n轮大循环
            for (int n = 2; n <= number; ++n) {  
    
                // 归零操作,因为随着s的变大,F(1,0), F(2,1), F(3,2),...,F(6,5)都不会出现,但是前面计算出现过F(1,1), F(2,2), F(3,3),...,F(5,5),
                //因为我们是交替使用前一个数组,所以必须作归零处理
                for (int i = 0; i < n; ++i)  
                    probabilities[1 - flag][i] = 0;  
    
                //第n轮数据之和为s∈[n, g_maxValue*n],然后计算每一个s的频数
                for (int s = n; s <= g_maxValue * n; ++s) {  
                    probabilities[1 - flag][s] = 0;   //  第n轮第n个数据初始化为0
    
                    //计算F(n, s) = F(n-1, s-1) + F(n-1, s-2) + F(n-1, s-3) + F(n-1, s-4) + F(n-1, s-5) + F(n-1, s-6) 
                    for (int j = 1; j <= s && j <= g_maxValue; ++j)  
                        probabilities[1 - flag][s] += probabilities[flag][s - j];  
                }  
                flag = 1 - flag;  
            }  
            double total = Math.pow(g_maxValue, number);  
            for (int i = number; i <= g_maxValue * number; i++) {  
                double ratio = (double) probabilities[flag][i] / total;  
                System.out.println(i);  
                System.out.println(ratio);  
            }  
        }  
    }  
    

    相关文章

      网友评论

          本文标题:n个骰子的点数和为s的概率集合输出(Java)

          本文链接:https://www.haomeiwen.com/subject/hishqftx.html