552. 学生出勤记录 II (Hard)
问题描述
可以用字符串表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤、迟到、到场)。记录中只含下面三种字符:
'A':Absent,缺勤'L':Late,迟到'P':Present,到场
如果学生能够 同时 满足下面两个条件,则可以获得出勤奖励:
- 按 总出勤 计,学生缺勤(
'A') 严格 少于两天。 - 学生 不会 存在 连续 3 天或 连续 3 天以上的迟到(
'L')记录。
给你一个整数 n ,表示出勤记录的长度(次数)。请你返回记录长度为 n 时,可能获得出勤奖励的记录情况
数量 。答案可能很大,所以返回对 10⁹ + 7 取余 的结果。
示例 1:
输入:n = 2
输出:8
解释:
有 8 种长度为 2 的记录将被视为可奖励:
"PP" , "AP", "PA", "LP", "PL", "AL", "LA", "LL"
只有"AA"不会被视为可奖励,因为缺勤次数为 2 次(需要少于 2 次)。
示例 2:
输入:n = 1
输出:3
示例 3:
输入:n = 10101
输出:183236316
提示:
1 <= n <= 10⁵
解题思路
dp思路1
考虑dp2[i][0]为只有迟到和到场两种情况下,第i + 1天迟到的情况数,dp2[i][1]为第i + 1天到场的情况数,则递推关系为:
dp2[i][1] = dp2[i - 1][0] + dp2[i - 1][1];dp2[i][0] = dp2[i - 1][1] + dp2[i - 1][0] - dp2[n - 3][1];
考虑dp[i][0]为第i + 1天迟到的情况数,dp[i][1]为第i + 1天到场的情况数,dp[i][2]为第i + 1天缺席的情况数,则递推关系有:
dp[i][1] = dp[i - 1][0] + dp[i - 1][1] + dp[i - 1][2];dp[i][2] = dp2[i - 1][0] + dp2[i - 1][1];dp[i][0] = dp[i - 1][1] + dp[i - 1][2] + dp[i - 1][0] - (dp[i - 3][1] + dp[i - 3][2]);
注意取模
dp思路2
代码
class Solution {
public:
int checkRecord(int n) {
if (n == 1)
return 3;
if (n == 2)
return 8;
if (n == 3)
return 19;
vector<vector<long long>> dp3(n + 1, vector<long long>(3, 0));
vector<vector<long long>> dp2(n, vector<long long>(2, 0));
int mod = 1000000007;
// 0表示迟到,1表示到场,2表示缺勤
dp2[0][0] = dp2[0][1] = 1;
dp2[1][0] = dp2[1][1] = 2;
dp2[2][0] = 3;
dp2[2][1] = 4;
for (int i = 3; i < n; i++) {
dp2[i][1] = (dp2[i - 1][0] % mod + dp2[i - 1][1] % mod) % mod;
dp2[i][0] = (dp2[i - 1][1] % mod + (dp2[i - 1][0] - dp2[i - 3][1] + mod) % mod) % mod;
}
dp3[0][1] = dp3[0][0] = dp3[0][2] = 1;
dp3[1][0] = 3, dp3[1][1] = 3, dp3[1][2] = 2;
dp3[2][0] = 3 + 2 + 3 - 1, dp3[2][1] = 8, dp3[2][2] = 4;
for (int i = 1; i < n; i++) {
dp3[i][2] = (dp2[i - 1][0] % mod + dp2[i - 1][1] % mod) % mod;
}
for (int i = 3; i < n; i++) {
dp3[i][0] = (dp3[i - 1][1] % mod + dp3[i - 1][2] % mod + (dp3[i - 1][0] - (dp3[i - 3][1] + dp3[i - 3][2]) + mod) % mod) % mod;
dp3[i][1] = (dp3[i - 1][1] % mod + dp3[i - 1][0] % mod + dp3[i - 1][2] % mod) % mod;
}
return (dp3[n - 1][0] + dp3[n - 1][1] + dp3[n - 1][2]) % mod;
}
};
552. 学生出勤记录 II (Hard)的更多相关文章
- Java实现 LeetCode 552 学生出勤记录 II(数学转换?还是动态规划?)
552. 学生出勤记录 II 给定一个正整数 n,返回长度为 n 的所有可被视为可奖励的出勤记录的数量. 答案可能非常大,你只需返回结果mod 109 + 7的值. 学生出勤记录是只包含以下三个字符的 ...
- Leetcode 552.学生出勤记录II
学生出勤记录II 给定一个正整数 n,返回长度为 n 的所有可被视为可奖励的出勤记录的数量. 答案可能非常大,你只需返回结果mod 109 + 7的值. 学生出勤记录是只包含以下三个字符的字符串: ' ...
- 552 Student Attendance Record II 学生出勤记录 II
给定一个正整数 n,返回长度为 n 的所有可被视为可奖励的出勤记录的数量. 答案可能非常大,你只需返回结果mod 109 + 7的值.学生出勤记录是只包含以下三个字符的字符串: 1.'A' : ...
- [Swift]LeetCode552. 学生出勤记录 II | Student Attendance Record II
Given a positive integer n, return the number of all possible attendance records with length n, whic ...
- 551.学生出勤记录I
/* * @lc app=leetcode.cn id=551 lang=java * * [551] 学生出勤记录 I * * https://leetcode-cn.com/problems/st ...
- Java实现 LeetCode 551 学生出勤记录 I(暴力大法好)
551. 学生出勤记录 I 给定一个字符串来代表一个学生的出勤记录,这个记录仅包含以下三个字符: 'A' : Absent,缺勤 'L' : Late,迟到 'P' : Present,到场 如果一个 ...
- 力扣(LeetCode)学生出勤记录I 个人题解
给定一个字符串来代表一个学生的出勤记录,这个记录仅包含以下三个字符: 'A' : Absent,缺勤 'L' : Late,迟到 'P' : Present,到场 如果一个学生的出勤记录中不超过一个' ...
- hiho1482出勤记录II(string类字符串中查找字符串,库函数的应用)
string类中有很多好用的函数,这里介绍在string类字符串中查找字符串的函数. string类字符串中查找字符串一般可以用: 1.s.find(s1)函数,从前往后查找与目标字符串匹配的第一个位 ...
- [LeetCode] 552. Student Attendance Record II 学生出勤记录之二
Given a positive integer n, return the number of all possible attendance records with length n, whic ...
- [LeetCode] Student Attendance Record II 学生出勤记录之二
Given a positive integer n, return the number of all possible attendance records with length n, whic ...
随机推荐
- python 小球碰撞游戏
#小球和挡板要自己找照片,放在一个单独文件夹,音乐也是一样的import pygame pygame.init()#游戏资源加载 a = 700#x轴为700 b = 800#y抽为800 sceee ...
- CH565/CH569W ETH-MAC例程现象使用说明
ETH-GMAC例程 使用MounRiver Studio(MRS)打开工程. 点击编译按键,编译完成出现0错误,0警告. 打开WCHISPTOOLS,芯片型号选择CH569或者CH565(根据评估版 ...
- 2021 & 2022年终回顾:山河无恙,烟火寻常
前言 又到了一年一度年终回顾的时候了,回想起去年年底圣诞节的时候由于忙着参加黑客松大赛,一下子就进入了新的一年,失去了年终回顾的动力,所以今年提前两个月开始进行回顾,这样的话今年最后一天就可以顺利发文 ...
- [编程基础] Python对象的浅拷贝与深拷贝笔记
Python中的赋值语句不创建对象的副本,它们只将名称绑定到对象.对于不可变的对象,这通常没有什么区别.但是对于处理可变对象或可变对象的集合,您可能需要寻找一种方法来创建这些对象的"真实副本 ...
- SICP:符号求导、集合表示和Huffman树(Python实现)
绪论 到目前为止,我们已经使用过的所有复合数据,最终都是从数值出发构造起来的(比如我们在上一篇博客<SICP 2.2: 层次性数据和闭包性质(Python实现)>所介绍的链表和树就基于数来 ...
- Python实现单项链表
单向链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. 表元素域ele ...
- 激光炸弹【算法竞赛进阶指南, HNOI2003】
激光炸弹 地图上有 \(N\) 个目标,用整数 \(Xi,Yi\)表示目标在地图上的位置,每个目标都有一个价值 \(Wi\). 注意:不同目标可能在同一位置. 现在有一种新型的激光炸弹,可以摧毁一个包 ...
- 使用阿里云产品搭建PHPWIND
2.4 安装PhpWind论坛网站 1. 本小节主要是在ECS云主机中快速安装PhpWind论坛网站的基础环境. 2. 远程登录到 PhpWind 主机服务器 ECS实例.请使用本实验 ...
- OpenMP 原子指令设计与实现
OpenMP 原子指令设计与实现 前言 在本篇文章当中主要与大家分享一下 openmp 当中的原子指令 atomic,分析 #pragma omp atomic 在背后究竟做了什么,编译器是如何处理这 ...
- 对象的变为私有方法不可改动 seal freeze