题目链接
今天的题比昨天难很多啊,很明显就是进阶版,题意昨天那篇博客解释过了,今天就不再解释一遍了,这题很明显是DP,记忆化搜索应该也行,但是我不确定是不是会爆掉,所以还是dp好点
我们设dp【i】【j】【k】为
第 i 天,缺席 j 次,连续迟到 k 次
那么依次进行分析
dp[i][0][0] = dp[i - 1][0][0] + dp[i - 1][0][1] + dp[i - 1][0][2] 。
今天截止0次缺席,今天截止0次连续迟到:过去一定也是0次缺席,但过去可以有0,1,2次连续迟到,因为只要我今天按时出席,过去的迟到记录都一笔勾销。
dp[i][1][0]=
dp[i - 1][1][0] + dp[i - 1][1][1] + dp[i - 1][1][2] +
dp[i - 1][0][0] + dp[i - 1][0][1] + dp[i - 1][0][2]
今天截止1次缺席,今天截止0次连续迟到:分两种情况:
a. 前三项,代表过去有1次缺席,今天没有缺席,但过去可以有0,1,2次连续迟到,因为只要我今天按时出席,过去的迟到记录都一笔勾销。
b. 后三项,代表过去有0次缺席,今天缺席了,但过去可以有0,1,2次连续迟到,因为只要我今天不迟到,过去的迟到记录都一笔勾销。
dp[i][0][1] = dp[i - 1][0][0];
今天截止0次缺席,今天截止1次连续迟到:过去0次缺席,过去0次迟到,今天迟到了。
dp[i][0][2] = dp[i - 1][0][1];
今天截止0次缺席,今天截止2次连续迟到:过去0次缺席,昨天迟到,今天迟到了。
dp[i][1][1] = dp[i - 1][1][0];
今天截止1次缺席,今天截止1次连续迟到:过去1次缺席,过去0次迟到,今天迟到了。这里可以仔细想一下,我今天必须要迟到,所以今天截止的1次缺席必定来自过去。
dp[i][1][2] = dp[i - 1][1][1];
今天截止1次缺席,今天截止2次连续迟到:过去1次缺席,昨天迟到,今天迟到了。
注:dp六种情况的分析取自龅牙叔,因为他讲的实在太好了,我想不到怎么讲的比他更好
然后将这些计算出来的可行状态累加便是答案
以下是代码
class Solution
{
public:
int MOD =1e9+7;
int checkRecord(int n)
{
long long dp[n][2][3];
dp[0][0][0] = 1;
dp[0][1][0] = 1;
dp[0][0][1] = 1;
for (int i = 1; i < n; i++)
{
dp[i][0][0] = (dp[i - 1][0][0] + dp[i - 1][0][1] + dp[i - 1][0][2]) % MOD;
dp[i][1][0] = (dp[i - 1][1][0] + dp[i - 1][1][1] + dp[i - 1][1][2]) % MOD;
dp[i][1][0] = (dp[i][1][0] + dp[i - 1][0][0] + dp[i - 1][0][1] + dp[i - 1][0][2]) % MOD;
dp[i][0][1] = dp[i - 1][0][0];
dp[i][0][2] = dp[i - 1][0][1];
dp[i][1][1] = dp[i - 1][1][0];
dp[i][1][2] = dp[i - 1][1][1];
}
long long ans = 0;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
ans = (ans + dp[n - 1][i][j]) % MOD;
}
}
return ans;
}
};
感谢您的观看