NOIP2015 子串
f[i][j][k][0]表示a做到前i位,b做到前j位,有了k个子串且第i位不用的方案数
f[i][j][k][1]表示a做到前i位,b做到前j位,有了k个子串且第i位用的方案数
a[i]==b[j]:
f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]
f[i][j][k][1]=f[i-1][j-1][k][1]+f[i-1][j-1][k-1][1]+f[i-1][j-1][k-1][0]
a[i]!=a[j]
f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]
f[i][j][k][1]=0
滚动数组优化即可通过本题
#include<cstdio>
using namespace std;
const long long mod=1000000007;
long long f[2][205][205][2];
int n,m,k;
char a[1005],b[1005];
int main(){
f[0][0][0][0]=f[1][0][0][0]=1ll;
scanf ("%d%d%d",&n,&m,&k);
scanf ("%s",a+1);scanf ("%s",b+1);
for (register int i=1;i<=n;++i){
for (register int j=1;j<=m;++j){
for (register int w=1;w<=k;++w){
if (a[i]==b[j]){
f[i%2][j][w][0]=f[(i-1)%2][j][w][0]+f[(i-1)%2][j][w][1];
f[i%2][j][w][1]=f[(i-1)%2][j-1][w][1]+f[(i-1)%2][j-1][w-1][1]+f[(i-1)%2][j-1][w-1][0];
}
else{
f[i%2][j][w][0]=f[(i-1)%2][j][w][0]+f[(i-1)%2][j][w][1];
f[i%2][j][w][1]=0;
}
f[i%2][j][w][0]%=mod;
f[i%2][j][w][1]%=mod;
}
}
}
printf ("%lld\n",(f[n%2][m][k][0]+f[n%2][m][k][1])%mod);
return 0;
}
浙公网安备 33010602011771号