Leetcode 552. 学生出勤记录 II 动态规划

Posted pxlsdz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode 552. 学生出勤记录 II 动态规划相关的知识,希望对你有一定的参考价值。

Leetcode 552. 学生出勤记录 II

题目描述

给定一个正整数 n,返回长度为 n 的所有可被视为可奖励的出勤记录的数量。
答案可能非常大,你只需返回结果模 109+7109+7 的值。

学生出勤记录是只包含以下三个字符的字符串:

  • \'A\' : Absent,缺勤
  • \'L\' : Late,迟到
  • \'P\' : Present,到场

如果一个学生的出勤纪录中不超过一个\'A\'(缺勤)并且不超过两个连续的\'L\'(迟到),那么这个学生会被奖赏。

样例

输入: n = 2
输出: 8
解释:
有8个长度为2的记录将被视为可奖励:
"PP" , "AP", "PA", "LP", "PL", "AL", "LA", "LL"
只有"AA"不会被视为可奖励,因为缺勤次数超过一次。

注意

  • n 的值不会超过 100000。

算法
(动态规划) O(n)
设计状态 f(i,j,k)表示已经完成了前 i次出勤记录,包含 j 个 ‘A‘ 和末尾连续 k 个 ‘L‘ 的方案数。初始 f(0,0,0)=1
状态转移:按照最后一个字母填的是什么划分即可,代码一看就懂。

class Solution {
public:
    int f[100005][2][3];
    const int MOD = 1000000007;
    int checkRecord(int n) {
       memset(f, 0, sizeof(f));
       f[0][0][0] = 1;
       for(int i = 0; i < n; i++){
           for(int j = 0; j <=1; j++){
               for(int k = 0; k <= 2; k++){
                   // 填写A
                   if(!j) f[i+1][j+1][0] = (f[i][j][k] + f[i+1][j+1][0]) % MOD;
                   // 填写P
                   f[i+1][j][0] = (f[i][j][k] + f[i+1][j][0]) % MOD;
                   // 填写L
                   if(k<=1) f[i+1][j][k + 1] = (f[i][j][k] + f[i+1][j][k + 1]) % MOD;
               }
           }
       }
       int res = 0;
       for(int j = 0; j <=1; j++){
           for(int k = 0; k <= 2; k++){
              res =(res + f[n][j][k]) % MOD;
           }
       }
       return res;
    }
};

以上是关于Leetcode 552. 学生出勤记录 II 动态规划的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 551. 学生出勤记录 I /552. 学生出勤记录 II(动态规划)/345. 反转字符串中的元音字母(set加入元素的方法)

LeetCode 552 学生出勤记录II[动态规划] HERODING的LeetCode之路

java 552.学生出勤记录II(1st).java

java 552.学生出勤记录II(1st).java

java 552.学生出勤记录II(1st).java

java 552.学生出勤记录II(1st).java