子串

大力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;
}
posted @ 2018-11-07 12:23  Splitor  阅读(151)  评论(0编辑  收藏  举报