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 }
STD

 

posted on 2016-10-31 10:24  Absolutezero  阅读(219)  评论(0编辑  收藏  举报