题目链接
链接: link.
自己思索的解法
我们观察题目可以容易获悉,学生的出勤记录中不能出现2个A,只能有1个或者没有A。所以分情况讨论,
当学生出勤记录没有A时,只存在P和L,且L不能连续出现3个,这就可以用动态规划的思想求解,每天有3个状态,L0(P),L1(这一天迟到了),L2(连续迟到两天了),很容易写出转移方程并求解。
当学生出勤记录只有一个A时,我们可以假设A出现在位置i,且将出勤记录分割成前后两个子出勤记录, 这两个子出勤记录时无关的,而且在第一种情况求解的过程中计算出来了,只需要将前后两段出勤记录的次数相乘,即可计算出第二种情况。
最后将第一二种情况相加即可。
class Solution {
public:
const int N = 1000000007;
//L0(P) L1 L2 L3
int checkRecord(int n) {
int dp[n + 1][3],ans = 0;
memset(dp,0,sizeof(dp));
dp[0][0] = 1;
dp[1][0] = 1; dp[1][1] = 1;
for(int i = 2; i <= n;++i){
dp[i][0] = ((dp[i-1][0] + dp[i-1][1])%N + dp[i-1][2]) % N;
dp[i][1] = (dp[i-1][0] ) % N;
dp[i][2] = (dp[i-1][1] ) % N;
}
ans = ((dp[n][0] + dp[n][1])%N + dp[n][2]) %N;
for(int i = 1; i <= n; ++i){
long long count1 = ((long long)(dp[n-i][0] + dp[n-i][1]) %N + dp[n-i][2]) % N;
long long count2 = ((long long)(dp[i-1][0] + dp[i-1][1]) %N + dp[i-1][2]) % N;
ans = (ans + (count1 * count2) % N) %N;
}
return ans;
}
};