又被“if(a=b)”坑了QAQ。。。写C++还是得开Warning,这么久了pascal还没改过来咋回事啊QWQ
题目大意就不说了OWO
网上的题解都不怎么看得懂啊。。。好像写得都很乱?还是我太sb了
f[i][j][k][0]表示A串前i个字符和B串前j个字符能够匹配,并且分成k段,a[i]不选。f[i][j][k][1]同理但a[i]要选。
于是。。。f[i][j][k][0]=f[i-1][j][k][1]+f[i-1][j][k][0];
if(a[i]==b[j])f[i][j][k][1]=f[i-1][j-1][k-1][0]+f[i-1][j-1][k][1]+f[i-1][j-1][k-1][1];
①第一维滚动②快速取模
字符串DP真的是我非常非常薄弱的一部分了,连状态设计都想了很久很久。。。
代码如下:
#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<algorithm> #define min(x,y) (x<y?x:y) #define MOD(x) (x>=mod?x-mod:x) using namespace std; const int maxn=500010,mod=1e9+7; int n,m,K; int f[2][210][210][2]; char s1[maxn],s2[maxn]; void read(int &k) { int f=1;k=0;char c=getchar(); while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar(); k*=f; } int main() { read(n);read(m);read(K); scanf("%s",s1+1);scanf("%s",s2+1); for(int i=1;i<=n;i++) { f[1][0][0][0]=f[0][0][0][0]=1; int up=min(i,m); for(int j=1;j<=up;j++) { for(int k=1;k<=K;k++) { if(s1[i]==s2[j]) f[i&1][j][k][1]=MOD(MOD(f[(i&1)^1][j-1][k][1]+f[(i&1)^1][j-1][k-1][0])+f[(i&1)^1][j-1][k-1][1]); else f[i&1][j][k][1]=0; if(j<i)f[i&1][j][k][0]=MOD(f[(i&1)^1][j][k][1]+f[(i&1)^1][j][k][0]); else f[i&1][j][k][0]=0; } } } printf("%d",MOD(f[n&1][m][K][1]+f[n&1][m][K][0])); }