题目描述
Given an integer n, your task is to count how many strings of length n can be formed under the following rules:
Each character is a lower case vowel (‘a’, ‘e’, ‘i’, ‘o’, ‘u’)
Each vowel ‘a’ may only be followed by an ‘e’.
Each vowel ‘e’ may only be followed by an ‘a’ or an ‘i’.
Each vowel ‘i’ may not be followed by another ‘i’.
Each vowel ‘o’ may only be followed by an ‘i’ or a ‘u’.
Each vowel ‘u’ may only be followed by an ‘a’.
Since the answer may be too large, return it modulo 10^9 + 7.
Example 1:
Input: n = 1
Output: 5
Explanation: All possible strings are: "a", "e", "i" , "o" and "u".
Example 2:
Input: n = 2
Output: 10
Explanation: All possible strings are: "ae", "ea", "ei", "ia", "ie", "io", "iu", "oi", "ou" and "ua".
Example 3:
Input: n = 5
Output: 68
Constraints:
1 <= n <= 2 * 10^4
思路
动态规划。dp[i][j]表示长度为i,以j为结尾,的串,个数。
根据限制条件可以推出每个字符前边的字符是什么,以当前字符结尾的个数为所有它前面可以出现的字符的个数之和。
代码
class Solution {
public:
int countVowelPermutation(int n) {
int MOD = 1e9+7;
vector<vector<long long int> > dp(n+1, vector<long long>(5+1, 0));
for (int i=1; i<=5; ++i) {
dp[1][i] = 1;
}
for (int i=2; i<=n; ++i) {
for (int j=1; j<=5; ++j) {
long long tmp = 0;
if (j == 1) {
tmp = (dp[i-1][2]%MOD + dp[i-1][3]%MOD + dp[i-1][5]%MOD)%MOD;
}else if (j == 2) {
tmp = (dp[i-1][3]%MOD + dp[i-1][1]%MOD)%MOD;
}else if (j == 3) {
tmp = (dp[i-1][4]%MOD + dp[i-1][2]%MOD)%MOD;
}else if (j == 4) {
tmp = dp[i-1][3]%MOD;
}else {
tmp = (dp[i-1][3]%MOD + dp[i-1][4]%MOD);
}
dp[i][j] += tmp;
dp[i][j] %= MOD;
}
}
long long res = 0;
for (int i=1; i<=5; ++i) {
res += dp[n][i];
res %= MOD;
}
return res;
}
};
最后不能直接求和然后取模,会超long long。
动态规划修行告一段落。甚至感觉比大学的时候理解的更深一点。
洗漱睡觉喽。