剑指 Offer 60. n个骰子的点数

题目地址

力扣 https://leetcode-cn.com/problems/nge-tou-zi-de-dian-shu-lcof/img

代码

class Solution {
    public double[] dicesProbability(int n) {
        int[][] dp = new int[n+1][6 * n+1];
		for (int i = 1;i < 7; ++i) {
			dp[1][i] = 1;
		}
		for (int i = 2; i <= n ; ++i ) {
			for (int j = i; j <= 6 * i ; j++ ) {
				for (int cur = 1; cur <= j - i + 1&&cur<=6; cur++ ) {
                    // d p[n][j]=\sum_{i=1}^{6} d p[n-1][j-i] 递推公式
					dp[i][j] += dp[i - 1][j - cur] ;
				}
			}
		}
		double total = Math.pow(6 , n);
		double[] res = new double[6*n-n+1];
		for (int i=n ; i<=6*n  ;++i ) {
			res[i-n] = ((double)dp[n][i] ) / total;
		}
	return res;
    }
}

递推公式

****d p[n][j]=\sum_{i=1}^{6} d p[n-1][j-i]

推导:

dp[1][1] = 1 dp[1][2] = 1 dp[1][3] = 1 dp[1][4] = 1 dp[1][5] = 1 dp[1][6] = 1

dp[2][2] = 1 dp[2][3] = 2 dp[2][4] = 3 dp[2][5] = 4 dp[2][6] = 5 dp[2][7] = 6

dp[2][8] = 5 dp[2][9] = 4 dp[2][10] = 3 dp[2][11] = 2 dp[2][12] = 1

dp[3][3] = 1 dp[3][4] = 3 dp[3][5] = ?

dp[3][5]=dp[3-1][5-1]+dp[3-1][5-2]+dp[3-1][5-3]=3+2+1=6

空间优化

我们知道,每个阶段的状态都只和它前一阶段的状态有关,因此我们不需要用额外的一维来保存所有阶段。

用一维数组来保存一个阶段的状态,然后对下一个阶段可能出现的点数 jj 从大到小遍历,实现一个阶段到下一阶段的转换。

这里注意:第二层j循环需要倒着进行动态规划,正着的话数据会被覆盖(留给读者自行思考)

class Solution {
    public double[] dicesProbability(int n) {
        int[] dp = new int[6 * n+1];
        for (int i = 1;i < 7; ++i) {
            dp[i] = 1;
        }
        for (int i = 2; i <= n ; ++i ) {
            for (int j = 6 * i; j >= i ; j-- ) {
                dp[j] = 0;
                for (int cur = 1; cur <= j - i + 1&&cur<=6; cur++ ) {
                    dp[j] += dp[j - cur] ;

                }

            }
        }
        double total = Math.pow(6 , n);
        double[] res = new double[6*n-n+1];
        for (int i=n ; i<=6*n  ;++i ) {
            res[i-n] = ((double)dp[i] ) / total;
        }
        return res;
    }
}

运行结果通过

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qdllhyRt-1649386810495)(C:\Users\shenxinbo\AppData\Roaming\Typora\typora-user-images\image-20220408105926571.png)]

上边的为优化后的,下面的是没优化过的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值