题解
比较简单的线性dp,dp[i][j][k][1]表示A串前i个,B串前j个,一共匹配了j组,这个字符是否匹配的
方案数,转移方程比较好想,但是这道题要用滚动数组(因为没清零调了半天),深刻认识到了
滚动数组的用法,注意两个连着的匹配也可以算作两组。
代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
const int MAXM = 205;
const int mod = 1e9+7;
int n,m,K;
int dp[2][MAXM][MAXM][2];
char ch[MAXN],c[MAXM];
int ans;
int main(){
scanf("%d%d%d",&n,&m,&K);
scanf("%s",ch+1);
scanf("%s",c+1);
dp[0][0][0][0]=1;
dp[1][0][0][0]=1; //!!!
for(register int i=1;i<=n;i++)
for(register int j=1;j<=min(i,m);j++){
for(register int k=1;k<=min(i,K);k++){
dp[i&1][j][k][0]=dp[i&1][j][k][1]=0; //超级重要!!!
dp[i&1][j][k][0]+=dp[(i-1)&1][j][k][0];
dp[i&1][j][k][0]%=mod;
dp[i&1][j][k][0]+=dp[(i-1)&1][j][k][1];
dp[i&1][j][k][0]%=mod;
if(ch[i]==c[j]){
dp[i&1][j][k][1]+=dp[(i-1)&1][j-1][k-1][0];
dp[i&1][j][k][1]%=mod;
dp[(i&1)][j][k][1]+=dp[(i-1)&1][j-1][k][1];
dp[i&1][j][k][1]%=mod;
dp[i&1][j][k][1]+=dp[(i-1)&1][j-1][k-1][1];
dp[i&1][j][k][1]%=mod;
}
// cout<<dp[i&1][j][k][0]<<" "<<dp[i&1][j][k][1]<<endl;
}
}
ans=dp[n&1][m][K][0]+dp[n&1][m][K][1];
ans%=mod;
printf("%d",ans);
return 0;
}