阿巴阿巴
NegaNebulus
2020-07-31 10:08:45
2020-07-31 10:25:30
#include<bits/stdc++.h>
using namespace std;
const int N=1005,M =205,mo=1000000007;
int n,m,K;
bool val=1;
char a[N],b[M ];
int f[2][M ][M ][2];/*f[i][j][k][0/1]
表示串a 中截止到i位使用k 个子串匹配串b 前j位字符,且串a 第i位选or不选的方案数*/
int main()
{
cin>>n>>m>>K;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=m;i++)
cin>>b[i];
f[0][0][0][0]=f[1][0][0][0]=1;//初始化
//dp
//无论如何,当第i位不选时 f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]
//当a[i]==b[j]时,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]
//因为每次状态转移只会用 f[i-1][j][k][0/1] 和 f[i][j][k][0/1],所以有了空间优化
for(int i=1;i<=n;i++,val^=1/*错开*/){
for(int j=1;j<=m;j++){
for(int k=1;k<=K;k++){
f[val][j][k][0]=(f[val^1][j][k][0]+f[val^1][j][k][1])%mo;
//状态转移
if(a[i]==b[j]){
f[val][j][k][1]=(f[val^1][j-1][k][1]+(f[val^1][j-1][k-1][0]+f[val^1][j-1][k-1][1])%mo)%mo;
//状态转移
}
else{//当然不选
f[val][j][k][1]=0;
}
}
}
}
cout<<(f[n&1][m][K][1]+f[n&1][m][K][0])%mo;//输出f[n][m][k][1]+f[n][m][k][0]
return 0;
}
共 11 条回复
我再来