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 ...
随机推荐
- 5、基于EasyExcel的导入导出
一.Apach POI处理Excel的方式: 传统Excel操作或者解析都是利用Apach POI进行操作,POI中处理Excel有以下几种方式: 1.HSSFWorkbook: HSSFWorkbo ...
- 关于asp.net mvc的控制器的依赖注入思考及对StructureMap依赖注入框架的简单实践笔记
写在前面: 依赖注入这个玩意很多人其实都接触过,但可能没有细究其中的原理. 比如Controller的构造函数中,只要你传入一些接口,应用自动就给你处理了创建的过程,无需你手动去new 一个实例并穿进 ...
- Java面试的一些面试题
10<<2=? tip:10的二进制为1010,左移两位即:101000,换算为十进制为2的5次方加上2的三次方等于40 答:40 1.dr-xr-xr-r解释一下权限的含义 tip: ...
- ArcObjects SDK开发 一些可直接调用的对话框
在ArcMap中,一些对话框是很复杂的,例如设置点线面样式的对话框,选择空间参考的对话框等,但这些对话框有些在ArcObjects SDK中是可以直接调用的. 1.空间参考选择设置对话框 弹出空间参考 ...
- [Leetcode]移除链表元素
题目 代码 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * Li ...
- Linux c 程序自动启动自己
在程序自动升级的时候需要自己重新启动自己 #include <stdio.h> #include <stdlib.h> #include <unistd.h> in ...
- C# 如何发送邮件消息
1.安装NUGET包 MailKit 2.代码如下 using MailKit.Net.Smtp; using MimeKit; using System.Collections.Generic; u ...
- 洛谷P1259 黑白棋子的移动 题解
本蒟蒻这题用的打表做法,其实也可以理解为是一种递推. 先来观察一下样例: 当n为7时,输出共有14行,易得输出行数为2n. ooooooo*******-- oooooo--******o* oooo ...
- angular---路由传参数
- 读Java8函数式编程笔记08_测试、调试和重构
1. Lambda表达式的单元测试 1.1. 单元测试是测试一段代码的行为是否符合预期的方式 1.2. Lambda表达式没有名字,无法直接在测试代码中调用 1.2.1. 将Lambda表达式放入一个 ...