dp
设f[i][j][l]表示A串取i个(但a[i]不一定能取到),B串取j个(b[j]一定能取到),此时用了l个串的方案数。
第一种情况:a[i]==b[j]
f[i][j][l]=f[i-1][j-1][l]+f[x][j-1][l-1]
第二种情况:a[i]!=b[j]
f[i][j][l]=0
到这里,已经拿到60分了。
又:每次的转移只跟这次和上次状态有关,
故再滚动数组优化即可。
对于时间复杂度,可以通过前缀和优化从o(n^2mk)降为o(nmk)
不过常数优化优化也勉勉强强能过
比如说…………
#define ll long long
const int N=1010,M=210;
const ll P=1000000007;
这些都去掉自己手写……就过了……
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 long long f[210][210][2]; 5 char a[1010],b[210]; 6 int main(){ 7 int n,m,maxl; 8 scanf("%d %d %d",&n,&m,&maxl); 9 scanf("%s%s",a+1,b+1); 10 for (int i=1;i<=n;i++) 11 for (int j=m;j>=1;j--) 12 for (int k=1;k<=maxl;k++){ 13 if (a[i]==b[j]){ 14 if (j==1){ 15 if (k==1){ 16 f[j][k][0]++; 17 f[j][k][1]=1; 18 } 19 } 20 else{ 21 f[j][k][0]+=f[j-1][k-1][0]; 22 f[j][k][1]=f[j-1][k-1][0]; 23 if (i>1&&a[i-1]==b[j-1]){ 24 f[j][k][1]+=f[j-1][k][1]; 25 f[j][k][0]+=f[j-1][k][1]; 26 } 27 } 28 } 29 else{ 30 f[j][k][1]=0; 31 } 32 f[j][k][0]%=1000000007; 33 f[j][k][1]%=1000000007; 34 } 35 printf("%lld",f[m][maxl][0]); 36 return 0; 37 }