LeetCode 1223. Dice Roll Simulation

原题链接在这里:https://leetcode.com/problems/dice-roll-simulation/

题目:

A die simulator generates a random number from 1 to 6 for each roll. You introduced a constraint to the generator such that it cannot roll the number i more than rollMax[i] (1-indexed) consecutive times.

Given an array of integers rollMax and an integer n, return the number of distinct sequences that can be obtained with exact n rolls.

Two sequences are considered different if at least one element differs from each other. Since the answer may be too large, return it modulo 10^9 + 7.

Example 1:

Input: n = 2, rollMax = [1,1,2,2,2,3]
Output: 34
Explanation: There will be 2 rolls of die, if there are no constraints on the die, there are 6 * 6 = 36 possible combinations. In this case, looking at rollMax array, the numbers 1 and 2 appear at most once consecutively, therefore sequences (1,1) and (2,2) cannot occur, so the final answer is 36-2 = 34.

Example 2:

Input: n = 2, rollMax = [1,1,1,1,1,1]
Output: 30

Example 3:

Input: n = 3, rollMax = [1,1,1,2,2,3]
Output: 181 

Constraints:

  • 1 <= n <= 5000
  • rollMax.length == 6
  • 1 <= rollMax[i] <= 15

题解:

Let dp[i][j][k] denotes number of distinct sequences up to i dice, ending with number j with k repeating j at the end.

For previous p, if j != p, then dp[i][j][1] = sum(dp[i - 1][p][k]), sum of previous ending with p, with k repeating p at the end.

Else if j == p, we need to make sure k + 1 <= rollMax[j], dp[i][j][k + 1] = dp[i - 1][j][k]. otherwise it would be 0.

Time Complexity: O(n*m*m*rMax). m = 6. rMax = max(rollMax[i]).

Space: O(n*m*rMax).

AC Java:

 1 class Solution {
 2     public int dieSimulator(int n, int[] rollMax) {
 3         int mod = 1000000007;
 4         int rMax = 15;
 5
 6         int [][][] dp = new int[n + 1][6][rMax + 1];
 7         for(int i = 0; i < 6; i++){
 8             dp[1][i][1] = 1;
 9         }
10
11         for(int i = 2; i <= n; i++){
12             for(int j = 0; j < 6; j++){
13                 for(int p = 0; p < 6; p++){
14                     for(int k = 1; k <= rMax; k++){
15                         if(j != p){
16                             dp[i][j][1] = (dp[i][j][1] + dp[i - 1][p][k]) % mod;
17                         }else if(k < rollMax[j]){ // same number, make sure k + 1 <= rollMax[j]
18                             dp[i][j][k + 1] = dp[i - 1][j][k];
19                         }
20                     }
21                 }
22             }
23         }
24
25         int res = 0;
26         for(int j = 0; j < 6; j++){
27             for(int k = 1; k <= rMax; k++){
28                 res = (res + dp[n][j][k]) % mod;
29             }
30         }
31
32         return res;
33     }
34 }

原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/12325988.html

时间: 2024-11-08 15:55:11

LeetCode 1223. Dice Roll Simulation的相关文章

LeetCode 1223. 掷骰子模拟 Dice Roll Simulation - Java - DP

题目链接:1223. 掷骰子模拟 有一个骰子模拟器会每次投掷的时候生成一个 1 到 6 的随机数. 不过我们在使用它时有个约束,就是使得投掷骰子时,连续 掷出数字 i 的次数不能超过 rollMax[i](i 从 1 开始编号). 现在,给你一个整数数组 rollMax 和一个整数 n,请你来计算掷 n 次骰子可得到的不同点数序列的数量. 假如两个序列中至少存在一个元素不同,就认为这两个序列是不同的.由于答案可能很大,所以请返回 模 \(10^9 + 7\) 之后的结果. 示例1: 输入:n =

Leetcode-5224 Dice Roll Simulation(掷骰子模拟)

1 typedef pair<int,int> P; 2 typedef long long ll; 3 #define _for(i,a,b) for(register int i = (a);i < b;i ++) 4 #define _rep(i,a,b) for(register int i = (a);i > b;i --) 5 #define INF 0x3f3f3f3f 6 #define MOD 1000000007 7 #define maxn 10003 8 #

hdu 5955 Guessing the Dice Roll 【AC自动机+高斯消元】

hdu 5955 Guessing the Dice Roll [AC自动机+高斯消元] 题意:给出 n≤10 个长为 L≤10 的串,每次丢一个骰子,先出现的串赢,问获胜概率. 题解:裸的AC自动机,求匹配到终止结点的概率,用 高斯消元?一开始不知道怎么建方程组,直接举个例子吧: Input: 1 2 2 1 1 2 1 图解: x0原本概率就是1,然后还要加上其他结点走向它的概率,,这样最后算下来是大于1的,现在还是觉得怪怪的... 1 #include <cstdio> 2 #inclu

hdu 5995 Guessing the Dice Roll(AC自动机+矩阵)

题目链接:hdu 5995 Guessing the Dice Roll 题意: 有一个6面的骰子,有n(n≤10)个人每个人猜了一个长度为l(l≤10)的序列,不停的掷骰子直到满足一个人的序列则那个人获胜,求每个人获胜的概率. 题解: 将他们猜的串插入AC自动机,然后转移k次,这里k要足够大才能收敛,然后因为总节点数最多才60个,所以用矩阵来加速. 正解应该是用高斯消元来做这个事情. 1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,

hdu5955 Guessing the Dice Roll【AC自动机】【高斯消元】【概率】【待补...】

2016沈阳区域赛http://acm.hdu.edu.cn/showproblem.php?pid=5955 Guessing the Dice Roll Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1632    Accepted Submission(s): 480 Problem Description There are N

HDU 5966 Guessing the Dice Roll

题意有 N≤10 个人,每个猜一个长度为L≤10的由1?6构成的序列,保证序列两两不同.不断地掷骰子,直到后缀与某人的序列匹配,则对应的人获胜.求每个人获胜的概率. 思路:建立trie图,跑高斯消元.高斯消元每个点的意义是:第i行第j列的值为x 有概率x从点j转移过来 1 const double eps = 1e-9; 2 const int SIGMA_SIZE = 7; 3 const int MAXNODE = 200; 4 5 int ch[MAXNODE][SIGMA_SIZE];

【AC自动机】【高斯消元】hdu5955 Guessing the Dice Roll

http://blog.csdn.net/viphong/article/details/53098489 我有一点不是很懂,这样算出来转移到AC自动机根节点的概率是一个远大于1的数. 按我的理解,因为转移初始就是从根节点出发的, 所以x(0)存储的是从根节点出发的概率(100%)+其他点转移到根节点的概率-- 比较抽象,还是当做套路记住吧--(鶸的做法) #include<cstdio> #include<cstring> #include<cmath> #inclu

C Primer Plus(第五版)12

第 12 章 存储类, 链接和内存管理 在本章中你将学习下列内容 . 关键字: auto, extern, static, register, const, volatile, restricted. . 函数: rand(), srand(), time(), malloc(), calloc(), free() . 在 C 中如何确定变量的作用域 ( 它在多大范围内可知) 以及变量的生存期 (它存在多长时间). . 设计更复杂的程序. C 的强大功能之一在于它允许你控制程序的细节. C 的内

进击的雨燕--------------协议

详情转自:http://wiki.jikexueyuan.com/project/swift/chapter2/07_Closures.html 协议定义了一个蓝图,规定了用来实现某一特定工作或者功能所必需的方法和属性.类,结构体或枚举类型都可以遵循协议,并提供具体实现来完成协议定义的方法和功能.任意能够满足协议要求的类型被称为遵循(conform)这个协议. 除了遵循协议的类型必须实现那些指定的规定以外,还可以对协议进行扩展,实现一些特殊的规定或者一些附加的功能,使得遵循的类型能够收益. 协议