noip2015 子串 dp

来源:互联网 发布:网络咨询大病种的方法 编辑:程序博客网 时间:2024/06/06 02:38

dp[i][j][k]表示A串匹配到第 i 位,B串匹配到第 j 位,分了k组的总方案数。后面再加0/1维表示第i位选或不选。
朴素DP会MLE,所以把第一维滚动起来。
dp[i][j][l][1] = dp[i-1][j-1][l-1][1] + dp[i-1][j-1][l-1][0] + dp[i-1][j-1][l][1];
dp[i][j][l][0] = dp[i-1][j][l][1] + dp[i-1][j][l][0];
时间复杂度:n×m×k。

#include<iostream>#include<cstdio>#define LL long longusing namespace std;char a[1005];char b[1005];int dp[2][205][205][2];int M=1e9+7;int main(){    int n,m,K;    int ans=0;    scanf("%d%d%d",&n,&m,&K);    scanf("%s",a+1);    scanf("%s",b+1);    for(int i=1;i<=n;i++)    {        if(a[i]==b[1])            dp[i%2][1][1][1]=1;        for(int j=1;j<=m;j++)        for(int l=1;l<=K;l++)        {            dp[i%2][j][l][0]=dp[(i+1)%2][j][l][0]+dp[(i+1)%2][j][l][1];            dp[i%2][j][l][0]%=M;            if(j==1&&l==1)            {                if(a[i]!=b[j])                dp[i%2][j][l][1]=0;            }            else            {                if(a[i]==b[j])                {                    dp[i%2][j][l][1]=dp[(i+1)%2][j-1][l-1][1]+dp[(i+1)%2][j-1][l-1][0];                    dp[i%2][j][l][1]%=M;                    dp[i%2][j][l][1]+=dp[(i+1)%2][j-1][l][1];                    dp[i%2][j][l][1]%=M;                }                else                    dp[i%2][j][l][1]=0;            }            if(j==m&&l==K)            {                ans+=dp[i%2][j][l][1];                ans%=M;            }        }    }    cout<<ans;    return 0;}
1 0
原创粉丝点击