题目描述
你现在需要设计一个密码 S,S 需要满足:
S 的长度是 N;
S 只包含小写英文字母;
S 不包含子串 T;
例如:abc 和 abcde 是 abcde 的子串,abd 不是 abcde 的子串。
请问共有多少种不同的密码满足要求?
由于答案会非常大,请输出答案模 109+7 的余数。
样例
2
a
625
算法1
//直接dp做,我看了前面3,4个的一点进去感觉没有熟悉的样子,就想写一种比较接单容易理解的
//状态机模型
//第一个是f[50][0]表示的是前面i个但是最后一个与模板字串不同,1则表示是相同的,表示的结尾是[i]
//那么这样的话对于每一个f[i][0]的转移方程就是应该是下面写的应该最后一个不相同的话那么不管前面怎么样都可以直接接上去,有因为有25个所以在乘上25
//对于最后一个是相同的话,那么就是原本应该的sum[i-1]在减去不符合的,不符合对于f[i-len][0]+f[i-len][1]表示的前缀一定干好就是答案,在乘上后门len只能有一种排法
`
//f[n][0]=(f[n-1][0]+f[n][1])*25,f[n][1]=(f[n-1][0]+f[n][1])*1-(f[n-m])
#include<iostream>
#include<cstring>
using namespace std;
const int N=60,mod=1e9+7;
long long f[N][2];
char ch[N];
int main(){
int n;
cin>>n;
cin>>ch;
f[0][0]=1;
f[0][1]=0;
int len=strlen(ch);
for(int i=1;i<=n;i++)
{
if(i<len)
{
f[i][0]=((f[i-1][0]+f[i-1][1])%mod*25)%mod;
f[i][1]=(f[i-1][0]+f[i-1][1])%mod;
}//在这之前是可以直接计算的
else {
f[i][0]=(((f[i-1][0]+f[i-1][1])%mod)*25)%mod;//仍然不变,因为不构成条件
f[i][1]=((f[i-1][0]+f[i-1][1])%mod-(f[i-len][0]+f[i-len][1])%mod+mod)%mod;
}
}
cout<<(f[n][0]+f[n][1])%mod<<endl;//最后也要取模
return 0;
}``