题目是P1220统计元音字母序列的数目
通过分析我们可以得知:
a前面只能接e、i、u
e前面只能接a或i
i前面只能接e、o
o前面只能接i
u前面只能接o、i
我们用dp[i]表示长度为i的字符串的个数,其中dp[i][j]表示dp[i]的5种状态,0≤j≤4。分别是以5个元音字母结尾的字符串。因此最终答案就是
d
p
[
n
]
[
0
]
+
d
p
[
n
]
[
1
]
+
d
p
[
n
]
[
2
]
+
d
p
[
n
]
[
3
]
+
d
p
[
n
]
[
4
]
dp[n][0]+dp[n][1]+dp[n][2]+dp[n][3]+dp[n][4]
dp[n][0]+dp[n][1]+dp[n][2]+dp[n][3]+dp[n][4]。
并且我们可以通过分析得知条件转移方程为:
d p [ n ] [ 0 ] = d p [ n − 1 ] [ 1 ] + d p [ n − 1 ] [ 2 ] + d p [ n − 1 ] [ 4 ] dp[n][0]=dp[n-1][1]+dp[n-1][2]+dp[n-1][4] dp[n][0]=dp[n−1][1]+dp[n−1][2]+dp[n−1][4]
d p [ n ] [ 1 ] = d p [ n − 1 ] [ 0 ] + d p [ n − 1 ] [ 2 ] dp[n][1]=dp[n-1][0]+dp[n-1][2] dp[n][1]=dp[n−1][0]+dp[n−1][2]
d p [ n ] [ 2 ] = d p [ n − 1 ] [ 1 ] + d p [ n − 1 ] [ 3 ] dp[n][2]=dp[n-1][1]+dp[n-1][3] dp[n][2]=dp[n−1][1]+dp[n−1][3]
d p [ n ] [ 3 ] = d p [ n − 1 ] [ 2 ] dp[n][3]=dp[n-1][2] dp[n][3]=dp[n−1][2]
d p [ n ] [ 4 ] = d p [ n − 1 ] [ 2 ] + d p [ n − 1 ] [ 3 ] dp[n][4]=dp[n-1][2]+dp[n-1][3] dp[n][4]=dp[n−1][2]+dp[n−1][3]
因为我们只需要储存前一个状态的信息,因此我们可以使用滚动数组优化,代码如下:
int countVowelPermutation(int n) {
long long mod = 1e9 + 7;
vector<long long> dp(5, 1);
vector<long long> ndp(5);
for (int i = 2; i <= n; ++i) {
/* a前面可以为e,u,i */
ndp[0] = (dp[1] + dp[2] + dp[4]) % mod;
/* e前面可以为a,i */
ndp[1] = (dp[0] + dp[2]) % mod;
/* i前面可以为e,o */
ndp[2] = (dp[1] + dp[3]) % mod;
/* o前面可以为i */
ndp[3] = dp[2];
/* u前面可以为i,o */
ndp[4] = (dp[2] + dp[3]) % mod;
dp = ndp;
}
return (dp[0]+dp[1]+dp[2]+dp[3]+dp[4])%mod;
}