bzoj 5220. 【GDOI2018模拟7.10】C 动态规划

来源:互联网 发布:淘宝开黑车 编辑:程序博客网 时间:2024/06/04 01:19

题意

这里写图片描述
|X|,|Y|<=1000

分析

比赛的时候想的水法,把每个pair看成一个点,然后建一个DAG后dp,水了90分。

正解:f[i,j]表示X当前到第i位,最后一位是与Y中的第j位匹配的方案数。直接枚举选与不选然后转移即可。

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;const int N=1005;const int MOD=1000000007;int n,m,f[N][N],g[N][N],nx[N][30],now[30];char s1[N],s2[N];int main(){    scanf("%s%s",s1+1,s2+1);    n=strlen(s1+1);m=strlen(s2+1);    for (int i=m;i>=0;i--)    {        for (int j=0;j<26;j++) nx[i][j]=now[j];        now[s2[i]-'a']=i;    }    //for (int i=1;i<=n;i++) f[i][now[s1[i]-'a']]=g[i][now[s1[i]-'a']]=1;    int L=0;    f[0][0]=1;    for (int i=0;i<n;i++)        for (int j=0;j<=m;j++)            if (f[i][j])            {                if (g[i][j]>g[i+1][j]) g[i+1][j]=g[i][j],f[i+1][j]=f[i][j];                else if (g[i][j]==g[i+1][j]) (f[i+1][j]+=f[i][j])%=MOD;                int k=nx[j][s1[i+1]-'a'];                if (k)                {                    if (g[i][j]+1>g[i+1][k]) g[i+1][k]=g[i][j]+1,L=max(L,g[i][j]+1),f[i+1][k]=f[i][j];                    else if (g[i][j]+1==g[i+1][k]) (f[i+1][k]+=f[i][j])%=MOD;                }            }    int ans=0;    for (int i=1;i<=m;i++)        if (g[n][i]==L) (ans+=f[n][i])%=MOD;    printf("%d",ans);    return 0;}
原创粉丝点击