題目描述:
有一個骰子模擬器會每次投擲的時候生成一個 1 到 6 的隨機數。
不過我們在使用它時有個約束,就是使得投擲骰子時,連續 擲出數字 i 的次數不能超過 rollMax[i](i 從 1 開始編號)。
現在,給你一個整數數組 rollMax 和一個整數 n,請你來計算擲 n 次骰子可得到的不同點數序列的數量。
假如兩個序列中至少存在一個元素不同,就認爲這兩個序列是不同的。由於答案可能很大,所以請返回 模 10^9 + 7 之後的結果。
示例 1:
輸入:n = 2, rollMax = [1,1,2,2,2,3]
輸出:34
解釋:我們擲 2 次骰子,如果沒有約束的話,共有 6 * 6 = 36 種可能的組合。但是根據 rollMax 數組,數字 1 和 2 最多連續出現一次,所以不會出現序列 (1,1) 和 (2,2)。因此,最終答案是 36-2 = 34。
示例 2:
輸入:n = 2, rollMax = [1,1,1,1,1,1]
輸出:30
示例 3:
輸入:n = 3, rollMax = [1,1,1,2,2,3]
輸出:181
提示:
1 <= n <= 5000
rollMax.length == 6
1 <= rollMax[i] <= 15
emm,兩層的dp好像並不行,看別人實現的用三層來實現的dp
尷尬的呀
class Solution {
public int dieSimulator(int n, int[] rollMax) {
int mod = 1000000007;
long [][][] f= new long[5000][6][16];
long [] g = new long[6];
for (int j=0;j<6;j++){
f[0][j][1] = 1;
g[j] = 1;
}
long now = 6;
for (int i =1;i<n;i++){
for (int j=0;j<6;j++){
for (int k=1;k<=15;k++){
if (k == 1){
f[i][j][k] = (now - g[j] + mod) % mod;
} else if (k<=rollMax[j]){
f[i][j][k] = f[i-1][j][k-1];
}
}
}
now = 0;
for (int j=0;j<6;j++) {
g[j] = 0;
for (int k = 1; k <= 15; k++) {
now = (now+ f[i][j][k] )% mod ;
g[j] = (g[j] + f[i][j][k]) % mod;
}
}
}
return (int)now;
}
}