题目链接:1223. 掷骰子模拟

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

时间复杂度: \(O(n×6^2)\)

空间复杂度: \(O(n)\)

Java代码:

class Solution {
private int mod = 1000000007; public int dieSimulator(int n,
int[] rollMax) {
long[][] dp = new long[n + 1][7]; for (int point = 1; point <= 6; ++point) {
dp[1][point] = 1;
} for (int i = 2; i <= n; ++i) {
for (int j = 1; j <= 6; ++j) {
dp[i][j] = getNum(dp, i, j, rollMax) % mod;
}
} long ret = 0;
for (int point = 1; point <= 6; ++point) {
ret += dp[n][point];
ret %= mod;
} if (ret < 0) {
ret += mod;
} return (int) ret;
} private long getNum(long[][] dp,
int i,
int j,
int[] rollMax) {
long ret = 0;
for (int point = 0; point <= 6; ++point) {
ret += dp[i - 1][point];
ret %= mod;
} int repeatNum = rollMax[j - 1];
// 去掉重复的统计数据
if (i > repeatNum) {
ret -= getRepeat(dp, i - 1, j, repeatNum);
ret %= mod;
} return ret;
} private long getRepeat( long[][] dp,
int i,
int j,
int repeatNum) {
if (i == repeatNum) {
return 1;
} if (repeatNum == 1) {
return dp[i][j];
} else {
long ret = 0;
for (int point = 1; point <= 6; ++point) {
if (point != j) {
ret += dp[i - repeatNum][point];
ret %= mod;
}
}
return ret;
}
}
}

Java代码:

// 2019年10月13日22:56:49
// 这是我自己写的,时间复杂度为O(n×6^3)
class Solution {
public int dieSimulator(int n, int[] rollMax) {
int mod = 1000000007;
long [][] arr = new long[n + 1][7];
Arrays.fill(arr[1], 1);
for (int i = 2; i <= n; ++i) {
for (int j = 1; j <= 6; ++j) {
if (rollMax[j - 1] == 1) {
for (int k = 1; k <= 6; ++k) {
if (k == j) {
continue;
}
arr[i][j] += arr[i - 1][k];
arr[i][j] %= mod;
}
continue;
}
if (i - rollMax[j - 1] < 1) {
for (int k = 1; k <= 6; ++k) {
arr[i][j] += arr[i - 1][k];
arr[i][j] %= mod;
}
continue;
}
for (int k = 1; k <= 6; ++k) {
if (k == j) {
for (int k1 = 1; k1 <= 6; ++k1) {
if (k1 != j) {
arr[i][j] += arr[i - rollMax[j - 1]][k1];
arr[i][j] %= mod;
}
}
continue;
}
arr[i][j] += arr[i - 1][k];
arr[i][j] %= mod;
}
}
}
long ret = 0;
for (long a : arr[n]) {
ret += a;
ret %= mod;
}
return (int) ret;
}
}

原文链接:https://blog.csdn.net/pfdvnah/article/details/102539644

LeetCode 1223. 掷骰子模拟 Dice Roll Simulation - Java - DP的更多相关文章

  1. 记忆化搜索模板题---leetcode 1155. 掷骰子的N种方法

    1155. 掷骰子的N种方法 这里有 d 个一样的骰子,每个骰子上都有 f 个面,分别标号为 1, 2, ..., f. 我们约定:掷骰子的得到总点数为各骰子面朝上的数字的总和. 如果需要掷出的总点数 ...

  2. python应用-掷骰子模拟-pygal

    pygal安装: Linux下: pip install pygal Windows下: python -m pip install pygal 效果如图: # -*- coding: utf-8 - ...

  3. LeetCode.874-走路机器人模拟(Walking Robot Simulation)

    这是悦乐书的第335次更新,第360篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第205题(顺位题号是874).网格上的机器人从点(0,0)开始并朝北.机器人可以接收三 ...

  4. 【HDOJ5955】Guessing the Dice Roll(概率DP,AC自动机,高斯消元)

    题意: 有n个人,每个人有一个长为L的由1~6组成的数串,现在扔一个骰子,依次记录扔出的数字,如果当前扔出的最后L个数字与某个人的数串匹配,那么这个人就算获胜,现在问每个人获胜的概率是多少. n,l& ...

  5. Python 使用matplotlib模块模拟掷骰子

    掷骰子 骰子类 # die.py 骰子类模块 from random import randint class Die(): """骰子类""&quo ...

  6. Python绘制直方图 Pygal模拟掷骰子

    #coding=utf-8 from random import randint class Die(): """骰子类""" def __ ...

  7. 使用python实现模拟掷骰子数据分析

    Data:2020/4/8 主题:模拟实现掷骰子数据分析 编译环境:pycharm 库:pygal 说明: code 1:创建一个掷骰子类对象,类方法获得掷骰子随机数1-6,默认6个面,模拟20次将结 ...

  8. Python Tkinter小实例——模拟掷骰子

    什么是Tkinter? Tkinter 是 Python 的标准 GUI 库.Python 使用 Tkinter 可以快速的创建 GUI 应用程序. 由于 Tkinter 是内置到 python 的安 ...

  9. 【NOIP2012模拟10.31】掷骰子

    题目 太郎和一只免子正在玩一个掷骰子游戏.有一个有N个格子的长条棋盘,太郎和兔子轮流掷一个有M面的骰子,骰子M面分别是1到M的数字.且掷到任意一面的概率是相同的.掷到几.就往前走几步.当谁走到第N格时 ...

随机推荐

  1. ent 基本使用 二 简单create && query

    接上文,前边我们了解了关于基本代码生成以及schema 迁移的学习,下边我们看看基本的数据操作 参考代码: https://github.com/rongfengliang/ent-demo 环境准备 ...

  2. 10-网页,网站,微信公众号基础入门(使用微信自带配置选项实现Airkiss配网)

    https://www.cnblogs.com/yangfengwu/p/11066036.html 如果提交失败多提交两次,只要上一节可以,,这一节一定可以的 如果没有设备 这个是我的二维码 咱就测 ...

  3. 浅谈LCA

    目录 什么是LCA 倍增求LCA dfs bfs 树剖求LCA 什么是LCA LCA就是最近公共祖先 对于有根树\(Tree\)的两个结点\(u.v\),最近公共祖先\(LCA(T,u,v)\)表示一 ...

  4. WIFI万能钥匙面试引出上线注意事项

    WEB应用上线程序员注意事项: 单元测试 前后端联调 界面和用户体验 DEBUG 性能 SEO 安全性

  5. 【AtCoder】 ARC 101

    link 搬来了曾经的题解 C-Candles 题意:数轴上有一些点,从原点开始移动到达这些点中的任意\(K\)个所需要的最短总路程 \(K\)个点必然是一个区间,枚举最左边的就行了 #include ...

  6. JavaScript初探系列(八)——DOM

    DOM(文档对象模型)是针对HTML和XML文档的一个API,描绘了一个层次化的节点树,允许开发人员添加.删除和修改页面的某一部分. HTML DOM 树形结构如下: 一.Node方面 (一).节点类 ...

  7. mvn常见参数命令讲解

    关于-N -N,--non-recursive Do not recurse into sub-projects 意思是,不递归到子项目(子模块). 举例: 一个父项目下Father面有3个子项目A. ...

  8. rtsp 客户端请求视频的时候支持输入用户名和密码的格式

    rtsp://[<username>[:<password>]@]<server-address-or-name>[:<port>][/<path ...

  9. 一句命令激活windows/office (https://03k.org/kms.html)

    https://03k.org/kms.html 本站上线KMS服务~一句命令激活windows/office kissshot2015年11月1日 装机必备, 软件下载 240 条评论 服务器地址: ...

  10. 【laravel5.5+Passport】laravel5的前后端分离之Passport设计

    项目中使用到了laravel5的passport组件,进行前后端分离的 api认证部分: 前后端分离的api认证,我们用的是: [密码授权令牌],需要用户登录->指定client_id/clie ...