首页 > 其他分享 > [leetcode每日一题]2.10

[leetcode每日一题]2.10

时间:2023-02-10 19:31:34浏览次数:58  
标签:投掷 状态 骰子 rollMax int 每日 点数 leetcode 2.10

​1223. 掷骰子模拟​

难度困难166

有一个骰子模拟器会每次投掷的时候生成一个 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​

Solution

动态规划。

首先官方题解的做法之一是,构造一个三维数组存储状态,分别记录当前掷的是第几个骰子、当前的点数、当前点数的连续出现次数。使用这个来进行动态规划的状态转移,其转移方程为:

 [leetcode每日一题]2.10_dp

然后,考虑到后一个状态只与前一个状态有关,那么可以进行状态压缩:

 [leetcode每日一题]2.10_dp_02

但是其实可以不用三维数组来表示,而采用二维数组并结合数学进行状态表示。

注意到如果骰子点数x允许连续y次的话,那么我可以通过最后一次投掷的点数不为x的其他所有点数的前y次投掷(即,当前为第z次的话,z-1,z-2,……,z-y)的和来转移到当前的状态。

同时,需要注意,如果可以的话,当前状态也可以从最初没有投掷任何一个骰子的状态转移而来。这是这种做法的一个难以想到的地方。

代码(C++)

class Solution {
public:
int dieSimulator(int n, vector<int>& rollMax) {
long long f[5001][6] = {0};
//初始状态设定
for(int i=0;i<6;i++)f[1][i] = 1;
for(int i=2;i<=n;i++){
for(int j=0;j<6;j++){
int cur = rollMax[j];
//即为上面讨论的特殊情况
if(i<=cur)f[i][j] += 1;
for(int k=1;k<=cur&&i>k;k++){
f[i][j] += f[i-k][0] + f[i-k][1] + f[i-k][2] + f[i-k][3] + f[i-k][4] +f[i-k][5] - f[i-k][j];
f[i][j] %= 1000000007;
}
}
}
// for(int i=0;i<=n;i++){
// for(int j=0;j<6;j++){
// cout<<f[i][j]<<" ";
// }
// cout<<endl;
// }
return int((f[n][0] + f[n][1] + f[n][2] + f[n][3] + f[n][4] + f[n][5])%1000000007);
}
};


标签:投掷,状态,骰子,rollMax,int,每日,点数,leetcode,2.10
From: https://blog.51cto.com/u_15763108/6049723

相关文章

  • 2.10学习记录
    typora掌握了typora的基础用法,包括但不限于标题的创建和子标题的设立以及更换代码环境其中标题创建是ctrl+数字数字代表几级标题子标题无序标题:星号+空格  快捷:ctr......
  • 2023.2.10 寒假集训总结【总】
    2023.2.10寒假集训总结【总】这次寒假集训时长24天,进行了快速的进度推进。从数据结构(主席树,线段树合并,分块,莫队)到图论(网络流,费用流),再到后来的dp(数据结构优化、单调队列优......
  • 【算法训练营day42】01背包问题基础 LeetCode416. 分割等和子集
    LeetCode416.分割等和子集题目链接:416.分割等和子集独上高楼,望尽天涯路一开始没有想到怎么转化成01背包问题,所以直接看题解找思路慕然回首,灯火阑珊处背包的体积为......
  • #yyds干货盘点# LeetCode面试题:正则表达式匹配
    1.简述:给你一个字符串 s 和一个字符规律 p,请你来实现一个支持'.' 和 '*' 的正则表达式匹配。'.'匹配任意单个字符'*'匹配零个或多个前面的那一个元素所谓匹配,是要......
  • #yyds干货盘点# LeetCode程序员面试金典:八皇后
    题目:设计一种算法,打印N皇后在N×N棋盘上的各种摆法,其中每个皇后都不同行、不同列,也不在对角线上。这里的“对角线”指的是所有的对角线,不只是平分整个棋盘的那两条对......
  • 2.10 Codeforces Round #851 (Div. 2)
    A-OneandTwo题意给出长度为n的序列a,a中元素是1或2找到一个k使a1*a2*a3*....*ak=ak+1*ak+2*ak+3*...*an思路统计序列中有多少个2,若是奇数个2,则......
  • LeetCode 19 -- Remove Nth Node From End of List
    ProblemGiventheheadofalinkedlist,removethe\(n\)-thnodefromtheendofthelistandreturnitshead.Example1Input:head=[1,2,3,4,5],n=2Outp......
  • LeetCode 559. Maximum Depth of N-ary Tree
    原题链接在这里:https://leetcode.com/problems/maximum-depth-of-n-ary-tree/description/题目:Givenan-arytree,finditsmaximumdepth.Themaximumdepthisthe......
  • LeetCode接雨水(/dp 单调栈 双指针)
    原题解题目给定n个非负整数表示每个宽度为1的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。约束题解解法一classSolution{public:inttra......
  • 代码随想录算法训练营第二十天|LeetCode 654.最大二叉树、LeetCode 617.合并二叉树、L
    654.最大二叉树文章:代码随想录(programmercarl.com)视频:又是构造二叉树,又有很多坑!|LeetCode:654.最大二叉树_哔哩哔哩_bilibili思路:最大二叉树的构建过程如下:构造......