一开始想记忆化搜索,想过可不可以分长度,,,很明显不可以,因为长度的边界不好搞,就是那三个连续的L
但是很明显感觉肯定是可以记忆的
范围 1e5,很明显只能跑一遍,也就是说,这里其实在暗示你用长度作为一个维度。
其实发现下一位可以上啥完全依赖于A的数量
以及连续的L的个数
那其实我们把这两个记录下来就好啊
记得大佬曾说你不会的时候就升维,那就开一个三维吧
但是连续的L 的个数
可以说是很难往下推,于是思路戛然而止。。。
翻了翻评论,发现说可以记录最后一位连续的L的个数1
想想有道理,你一位一位推,然后可以把连续三个L直接杀死在襁褓里
思路又来了,不过一开始写错了:
忽略最后一维的含义啊,是连续
,也就是dp[x][0][i-1]完全可以由dp[x][2][i-1]和dp[x+1][2][i-1]转移过来,,,
应该是这样,第二个那个,只要在i-1后面加的是P,就直接可以把第二维变成0
dp[0][0][i]=(dp[0][1][i-1]+dp[0][0][i-1]+dp[0][2][i-1])%1000000007;//dp[1][x][x]可没法变成0个A
dp[1][0][i]=(dp[1][2][i-1]+dp[1][1][i-1]+dp[1][0][i-1]+dp[0][0][i-1]+dp[0][1][i-1]+dp[0][2][i-1])%1000000007;
dp[0][1][i]=(dp[0][0][i-1])%1000000007;
dp[0][2][i]=(dp[0][1][i-1])%1000000007;
dp[1][1][i]=(dp[1][0][i-1])%1000000007;
dp[1][2][i]=(dp[1][1][i-1])%1000000007;
最后,初始化的话,除了三个为1 以外其他为0 就行
dp[0][0][1] = 1;
dp[1][0][1] = 1;
dp[0][1][1] = 1;
最后求得是个方案数,得把上面六种都加起来然后返回就行
最后总结一下,dp问题不要忘记是一直算到n,注意初始化+状态转移,即可。
三维数组也不要怕MLE,其实你可以看到第一二维都就到2,所以相当于一个1e5的一维数组,其实根本不要紧的
对了,有可能中间结果溢出(昨天遇见一个题,取到Int的上界了,你可以直接开long long)或者加一个数就模一下,就像刚刚有过加六个数的很难说不会越界
class Solution {
public:
int checkRecord(int n) {
long long dp[3][4][100006]={0};
dp[0][0][1] = 1;
dp[1][0][1] = 1;
dp[0][1][1] = 1;
for(int i=2;i<=n;i++){
dp[0][0][i]=(dp[0][1][i-1]+dp[0][0][i-1]+dp[0][2][i-1])%1000000007;//dp[1][x][x]可没法变成0个A
dp[1][0][i]=(dp[1][2][i-1]+dp[1][1][i-1]+dp[1][0][i-1]+dp[0][0][i-1]+dp[0][1][i-1]+dp[0][2][i-1])%1000000007;
dp[0][1][i]=(dp[0][0][i-1])%1000000007;
dp[0][2][i]=(dp[0][1][i-1])%1000000007;
dp[1][1][i]=(dp[1][0][i-1])%1000000007;
dp[1][2][i]=(dp[1][1][i-1])%1000000007;
}
return (dp[0][0][n]+ dp[0][1][n]+dp[1][0][n]+dp[0][2][n]+ dp[1][1][n]+dp[1][2][n])%1000000007;
}
};