这道题最开始的想法是参考POJ的这道题,建自动机然后矩阵快速幂,因为题目有点相似。但后来仔细想了一下还是不好做,因为我们不允许的substring是LLL, LLLL...,数量太多,所以我们还是退而求其次用dp来接这道题。我们用dp[i][j][k]表示长度为i,有j个A并且结尾有k个L的情况下,distinct string的数量。显然j, k 满足条件 0 <= j <= 1 && 0 <= k <= 2。我们有递推公式:
- dp[i][0][0] = dp[i - 1][0][0] + dp[i - 1][0][1] + dp[i - 1][0][2]
- dp[i][0][1] = dp[i - 1][0][0]
- dp[i][0][2] = dp[i - 1][0][1]
- 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]
- dp[i][1][1] = dp[i - 1][1][0]
- dp[i][1][2] = dp[i - 1][1][1]
按照递推公式计算即可,最后统计所有长度为i满足条件的数量,用rolling array可以优化成常数空间,时间复杂度O(n),代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
int checkRecord(int n) { | |
const int MOD = 1000000007; | |
//dp[i][j][k], represent # of all possibe attendance record with length i, | |
//j As and ends with k Ls, where 0 <= j <= 1 && 0 <= k <= 2 | |
//dp[i][0][0] = dp[i - 1][0][0] + dp[i - 1][0][1] + dp[i - 1][0][2] | |
//dp[i][0][1] = dp[i - 1][0][0] | |
//dp[i][0][2] = dp[i - 1][0][1] | |
//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] | |
//dp[i][1][1] = dp[i - 1][1][0] | |
//dp[i][1][2] = dp[i - 1][1][1] | |
vector<vector<vector<int>>> dp(2, vector<vector<int>>(2, vector<int>(3, 0))); | |
//init | |
dp[0][0][0] = 1; | |
dp[0][0][1] = 1; | |
dp[0][0][2] = 0; | |
dp[0][1][0] = 1; | |
dp[0][1][1] = 0; | |
dp[0][1][2] = 0; | |
//dp, rolling array | |
int e = 1; | |
for(int i = 2; i <= n; ++i, e ^= 1) | |
{ | |
dp[e][0][0] = ((dp[e ^ 1][0][0] + dp[e ^ 1][0][1]) % MOD + dp[e ^ 1][0][2]) % MOD; | |
dp[e][0][1] = dp[e ^ 1][0][0]; | |
dp[e][0][2] = dp[e ^ 1][0][1]; | |
dp[e][1][0] = ((dp[e ^ 1][1][0] + dp[e ^ 1][1][1]) % MOD + dp[e ^ 1][1][2]) % MOD; | |
dp[e][1][0] += dp[e][0][0]; | |
dp[e][1][0] %= MOD; | |
dp[e][1][1] = dp[e ^ 1][1][0]; | |
dp[e][1][2] = dp[e ^ 1][1][1]; | |
} | |
//count | |
int res = 0; | |
for(int j = 0; j <= 1; ++j) | |
{ | |
for(int k = 0; k <= 2; ++k) | |
{ | |
res += dp[e ^ 1][j][k]; | |
res %= MOD; | |
} | |
} | |
return res; | |
} | |
}; |
No comments:
Post a Comment