掷色子模拟

一、题目描述

题目链接:https://leetcode-cn.com/problems/dice-roll-simulation/

 

二、题目分析

题解参考:https://leetcode-cn.com/problems/dice-roll-simulation/solution/java-dp-zhe-ti-shi-you-dian-nan-du-de-medpian-hard/

当我们掷色子的时候,投出什么点数都跟前面的点数无关,但是题目给了一点限制,就是连续的点数不能超过某一个值,因此这是一个有限制的排列。

对于这种设计连续的题目,可以考虑用高维数组来解决。这里我们使用dp[i][j][k]来表示,在投 i 次的情况下,以连续的 k 次 j 点数结尾的排列组合。这里k有两种种情况。

1、k = 1,即以一个 j 结尾,那么前面的点数就不能为 j ,因此要将各种 i-1 的所有可能相加(除了与结尾相同的数)

2、k > 1,在这种情况下,假设我们要投一个4出来,说明前面的最后的点数也得是4,才能达到连续的要求。

要注意我们上面所说的都是跟前面的点数相关,因此要考虑一种特殊情况,即如果只有一次投掷,那么就每种点数只有一种情况,就是自己。

 

三、代码

public int dieSimulator(int n, int[] rollMax) {
        int[][][] dp = new int[n+1][6][16];
        int MOD = (int) (1e9+7);
        for (int i = 1; i <= n; ++i) {
            for (int j = 0; j < 6; j++) {
                if (i == 1) {
                    dp[i][j][1] = 1;
                    continue;
                }
                for (int k = 1; k <= rollMax[j]; ++k) {
                    if (k > 1) {
                        dp[i][j][k] = dp[i-1][j][k-1] % MOD;
                    } else {
                        int sum = 0;
                        for (int jj = 0; jj < 6; ++jj) {
                            if (jj == j) continue;
                            for (int kk = 1; kk <= rollMax[jj]; ++kk) {
                                sum = (sum + dp[i-1][jj][kk]) % MOD;
                            }
                        }
                        dp[i][j][k] = sum;
                    }
                }
            }
        }
        int res = 0;
        for (int i = 0; i < 6; ++i) {
            for (int k = 1; k <= rollMax[i]; ++k) {
                res = (res + dp[n][i][k]) % MOD;
            }
        }
        return res;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值