子串
大力dp
首先设出状态:dp[i][j][k][0/1]代表了匹配到了a串的第i位,b串的第j位,已经选出了k次,这一位是否必须选,然后转移见代码吧qwq:
空间可能吃不消,用滚动数组优化第一位
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#define maxn 506
#define SZJ signed
#include<time.h>
#define AK main
#define half (l+r)>>1
#define SDOI ()
#define mod 1000000007
using namespace std;
#define rep(i,a,b) for (int i=a;i<=b;++i)
#define dep(i,a,b) for (int i=a;i>=b;i--)
#define erep(i,a) for (int i=head[a];i!=-1;i=e[i].next)
#define lson t[s].lc
#define rson t[s].rc
int dp[3][201][201][2],m,n,mx;
char ch1[1002],ch2[1002];
SZJ AK SDOI
{
cin>>n>>m>>mx;
scanf("%s",ch1+1);
scanf("%s",ch2+1);
dp[0][0][0][0]=dp[1][0][0][0]=1;
rep(i,1,n)
{
rep(j,1,min(i,m))
rep(k,1,min(mx,j))
{
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 (ch1[i]==ch2[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;
}
}
memset(dp[(i-1)&1],0,sizeof(dp[(i-1)&1]));
dp[(i-1)&1][0][0][0]=1;
}
int ans=dp[n&1][m][mx][1];
ans=(ans+dp[n&1][m][mx][0])%mod;
cout<<ans;
}