算法学习之n个骰子的点数

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

思路:因为暴力递归效率很低,这里我就没去看了。看一下优化的方法使用for循环

有些类似动态规划,因为f(n) = f(k-1)+f(k-2)...f(k-6),意思也就是我们当前所求的n个骰子和为k的次数=和为k-1出现次数+和为k-2出现次数+...和为k-6出现次数的总和。本质就是多投入一个骰子因为6个面6个点数的存在累加了1-6出现不同的情况总和。基于这种思想看代码就基本理解了。

其中的E二维数组是用来循环存储上一次值得,所以复用的时候不能忘了重置

 public void printProbability(int number) {
        if (number <= 0) return;

        int maxValue = 6;
        int flag = 0;
        int[][] probabilites = new int[2][maxValue * number + 1];

        // 首先初始化第一个骰子,每个点数出现的次数为1
        for (int i = 1; i <= maxValue; i++) {
            probabilites[flag][i] = 1;
        }

        // 从第二个骰子至第n个骰子做计算
        // 骰子为k时,sum取值范围为k~k*maxValue
        for (int k = 2; k <= number; k++) {
            flag = 1 - flag;
            // 在开始统计前先清除要用的数字(<k的)
            for (int i = 1; i < k; i++) {
                probabilites[flag][i] = 0;
            }
            // k个骰子点数范围在k~k*maxValue,k处的先置0在进行计算
            for (int i = k; i <= maxValue * k; i++) {
                // 在计数前先清零该位置
                probabilites[flag][i] = 0;
                int count = 1;
                while (i - count > 0 && count <= 6) {
                    probabilites[flag][i] += probabilites[1 - flag][i - count];
                    count++;
                }
            }
        }
        // 开始打印
        DecimalFormat decimalFormat = new DecimalFormat("0.000");
        double pow = Math.pow(maxValue, number);
        for (int i = number; i <= maxValue * number; i++) {
            String probability = decimalFormat.format(probabilites[flag][i] / pow);
            System.out.println(probability + "");
        }

    }

时间复杂度:O(mn)

空间复杂度:O(mn)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值