剑指 Offer 60. n个骰子的点数 --- 动态规划

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

剑指 Offer 60. n个骰子的点数
把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。
你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。
示例 1:
输入: 1
输出: [0.16667,0.16667,0.16667,0.16667,0.16667,0.16667]
示例 2:
输入: 2
输出: [0.02778,0.05556,0.08333,0.11111,0.13889,0.16667,0.13889,0.11111,0.08333,0.05556,0.02778]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/nge-tou-zi-de-dian-shu-lcof

表示状态

用二维数组 dp [ i ] [ j ] ,i 行表示第 n 个骰子的所有点数集合,j 列表示 可能出现的数字 个数

状态转移方程

单单看第 nn 枚骰子,它的点数可能为 1 , 2, 3, … , 6因此投掷完 nn 枚骰子后点数 jj 出现的次数,可以由投掷完 n-1 枚骰子后,对应点数 j-1, j-2, j-3, … , j-6 出现的次数之和转化过来。

第n枚骰子的点数 
j为上一层可能数字的 个数
for (i = 1; i <= 6; i ++) {
    dp[n][j] += dp[n-1][j - i]
}

注意:j - i 不能为负数

边界处理

投掷完 1 枚骰子后,它的可能点数分别为 1, 2, 3, … , 6,并且每个点数出现的次数都是 1 .

for (int i = 1; i <= 6; i ++) {
    dp[1][i] = 1;
}

具体代码

class Solution {
    public double[] dicesProbability3(int n) {
        //声明 n 行,最大数字和为 n*6 的二维数组
        int[][] dp = new int[n + 1][6 * n + 1];
        //初始化数据,当 n 为 1 时,分别 1-6 都各 1 次
        for(int i = 1; i <= 6; i++)
            dp[1][i] = 1;
        //每多一个骰子进行处理,i表示骰子的个数
        for(int i = 2; i <= n; i++)
            //循环所有 有的数字,因为 i 个骰子最小的数为 i,所以从 i 下标循环,最大数字为 6 * i
            for(int j = i; j <= 6 * i; j++)
                //数字和有可能分别通过 +1,+2,+3,+4,+5,+6的操作得到,所以分别加上上一层的 -1,-2,-3,-4,-5,-6的个数
                //还有一个前提就是,j-k >= 0 ,也就是 k <= j
                for(int k = 1; k <= 6 && k <= j; k++)
                    dp[i][j] += dp[i-1][j - k];
        //声明结果数组,长度为 6 * n - n + 1
        double[] ans = new double[6 * n - n + 1];
        //每个数字和 对应的 次数 / 总次数 ,得到结果
        //总次数为 6的n次方
        for(int i = n; i <= 6 * n; i++)
            ans[i - n] = ((double)dp[n][i]) / (Math.pow(6,n));
        return ans;
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值