my
动规的五步:定义;推导公式;初始化;遍历顺序;打表验证
- 定义的思考角度
一开始我的想法是:f[i][j],以第i个字母为结尾的长度为j的字符串的数目
但是这样就要求了一件事:
如果我是在第i位去猜测第i-1位的可能性,那么我需要逆着题目条件去判断 第i位 前面那位字母是谁,有些许滴麻烦
因此我们可以通过 在第 i 位时就去推导 第i+1位
- 推导公式
\(f[当前的元素][j+1] += f[合法的前面元素][j]\)
- 初始化
所有长度为1时都是1,只有它自己
- 遍历顺序
必须要先推导出前面元素的状态,这里是有先后关系的,01背包里的是没有前后顺序的,因为一个物品只关心会不会被选,此时不能优化为一维
- 打表
代码部分是三叶姐姐滴
class Solution {
public:
int MOD = (int)1e9+7;
int countVowelPermutation(int n) {
long f[6][20010];//以i结尾的长度为j的字符串个数
memset(f,0,sizeof f);
//初始化
for(int i = 1;i<=5;i++)f[i][1] = 1;
//遍历顺序
for(int j = 1;j<n;j++){
// 每个元音 'a' 后面都只能跟着 'e'
f[2][j + 1] += f[1][j];
// 每个元音 'e' 后面只能跟着 'a' 或者是 'i'
f[1][j + 1] += f[2][j];
f[3][j + 1] += f[2][j];
// 每个元音 'i' 后面 不能 再跟着另一个 'i'
f[1][j + 1] += f[3][j];
f[2][j + 1] += f[3][j];
f[4][j + 1] += f[3][j];
f[5][j + 1] += f[3][j];
// 每个元音 'o' 后面只能跟着 'i' 或者是 'u'
f[3][j + 1] += f[4][j];
f[5][j + 1] += f[4][j];
// 每个元音 'u' 后面只能跟着 'a'
f[1][j + 1]+= f[5][j];
for(int i = 1;i<=5;i++)f[i][j+1] %= MOD;
}
long ans = 0;
for (int i = 1; i <= 5; i++) ans += f[i][n];
return (int)(ans % MOD);
}
};
标签:初始化,推导,int,字母,LC1220,元音,数目
From: https://www.cnblogs.com/hereskiki/p/16974473.html