问题描述

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)的更多相关文章

  1. Java实现 LeetCode 552 学生出勤记录 II(数学转换?还是动态规划?)

    552. 学生出勤记录 II 给定一个正整数 n,返回长度为 n 的所有可被视为可奖励的出勤记录的数量. 答案可能非常大,你只需返回结果mod 109 + 7的值. 学生出勤记录是只包含以下三个字符的 ...

  2. Leetcode 552.学生出勤记录II

    学生出勤记录II 给定一个正整数 n,返回长度为 n 的所有可被视为可奖励的出勤记录的数量. 答案可能非常大,你只需返回结果mod 109 + 7的值. 学生出勤记录是只包含以下三个字符的字符串: ' ...

  3. 552 Student Attendance Record II 学生出勤记录 II

    给定一个正整数 n,返回长度为 n 的所有可被视为可奖励的出勤记录的数量. 答案可能非常大,你只需返回结果mod 109 + 7的值.学生出勤记录是只包含以下三个字符的字符串:    1.'A' : ...

  4. [Swift]LeetCode552. 学生出勤记录 II | Student Attendance Record II

    Given a positive integer n, return the number of all possible attendance records with length n, whic ...

  5. 551.学生出勤记录I

    /* * @lc app=leetcode.cn id=551 lang=java * * [551] 学生出勤记录 I * * https://leetcode-cn.com/problems/st ...

  6. Java实现 LeetCode 551 学生出勤记录 I(暴力大法好)

    551. 学生出勤记录 I 给定一个字符串来代表一个学生的出勤记录,这个记录仅包含以下三个字符: 'A' : Absent,缺勤 'L' : Late,迟到 'P' : Present,到场 如果一个 ...

  7. 力扣(LeetCode)学生出勤记录I 个人题解

    给定一个字符串来代表一个学生的出勤记录,这个记录仅包含以下三个字符: 'A' : Absent,缺勤 'L' : Late,迟到 'P' : Present,到场 如果一个学生的出勤记录中不超过一个' ...

  8. hiho1482出勤记录II(string类字符串中查找字符串,库函数的应用)

    string类中有很多好用的函数,这里介绍在string类字符串中查找字符串的函数. string类字符串中查找字符串一般可以用: 1.s.find(s1)函数,从前往后查找与目标字符串匹配的第一个位 ...

  9. [LeetCode] 552. Student Attendance Record II 学生出勤记录之二

    Given a positive integer n, return the number of all possible attendance records with length n, whic ...

  10. [LeetCode] Student Attendance Record II 学生出勤记录之二

    Given a positive integer n, return the number of all possible attendance records with length n, whic ...

随机推荐

  1. 5、基于EasyExcel的导入导出

    一.Apach POI处理Excel的方式: 传统Excel操作或者解析都是利用Apach POI进行操作,POI中处理Excel有以下几种方式: 1.HSSFWorkbook: HSSFWorkbo ...

  2. 关于asp.net mvc的控制器的依赖注入思考及对StructureMap依赖注入框架的简单实践笔记

    写在前面: 依赖注入这个玩意很多人其实都接触过,但可能没有细究其中的原理. 比如Controller的构造函数中,只要你传入一些接口,应用自动就给你处理了创建的过程,无需你手动去new 一个实例并穿进 ...

  3. Java面试的一些面试题

    ​ 10<<2=? tip:10的二进制为1010,左移两位即:101000,换算为十进制为2的5次方加上2的三次方等于40 答:40 1.dr-xr-xr-r解释一下权限的含义 tip: ...

  4. ArcObjects SDK开发 一些可直接调用的对话框

    在ArcMap中,一些对话框是很复杂的,例如设置点线面样式的对话框,选择空间参考的对话框等,但这些对话框有些在ArcObjects SDK中是可以直接调用的. 1.空间参考选择设置对话框 弹出空间参考 ...

  5. [Leetcode]移除链表元素

    题目 代码 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * Li ...

  6. Linux c 程序自动启动自己

    在程序自动升级的时候需要自己重新启动自己 #include <stdio.h> #include <stdlib.h> #include <unistd.h> in ...

  7. C# 如何发送邮件消息

    1.安装NUGET包 MailKit 2.代码如下 using MailKit.Net.Smtp; using MimeKit; using System.Collections.Generic; u ...

  8. 洛谷P1259 黑白棋子的移动 题解

    本蒟蒻这题用的打表做法,其实也可以理解为是一种递推. 先来观察一下样例: 当n为7时,输出共有14行,易得输出行数为2n. ooooooo*******-- oooooo--******o* oooo ...

  9. angular---路由传参数

  10. 读Java8函数式编程笔记08_测试、调试和重构

    1. Lambda表达式的单元测试 1.1. 单元测试是测试一段代码的行为是否符合预期的方式 1.2. Lambda表达式没有名字,无法直接在测试代码中调用 1.2.1. 将Lambda表达式放入一个 ...