一、题目描述
题目链接:https://leetcode-cn.com/problems/dice-roll-simulation/
二、题目分析
当我们掷色子的时候,投出什么点数都跟前面的点数无关,但是题目给了一点限制,就是连续的点数不能超过某一个值,因此这是一个有限制的排列。
对于这种设计连续的题目,可以考虑用高维数组来解决。这里我们使用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;
}