• Luogu P2516 [HAOI2010]最长公共子序列 DP


    首先$LIS$显然:$f[i][j]=max(f[i][j-1],f[i-1][j],(a[i]==b[j])*f[i-1][j-1])$

    考虑如何转移数量:

    首先,不管$a[i]$是否等于$b[j]$,

    都有$h[i][j]+=h[i-1][j]*(f[i][j]==f[i-1][j])+h[i][j-1]*(f[i][j]==f[i][j-1])$

    然后讨论$LIS$中第三种转移:

    如果$a[i]==b[j] && f[i][j]==f[i-1][j-1]+1$,有$h[i][j]+=h[i-1][j-1]$

    而如果$a[i]!=b[j] && f[i][j]==f[i-1][j-1]$,有$h[i][j]-=h[i-1][j-1]$,此处是考虑$h[i-1][j]$与$h[i][j-1]$对答案的重复转移,所以要减去;

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define R register int
    using namespace std;
    namespace Fread {
        static char B[1<<15],*S=B,*D=B;
        #define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
        inline int g() {
            R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
            do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
        } inline bool isempty(const char& ch) {return ch<=36||ch>=127;}
        inline void gs(char* s) {register char ch; while(isempty(ch=getchar())); do *s++=ch; while(!isempty(ch=getchar()));}
    }using Fread::g; using Fread::gs;
    const int N=500010,M=1E+8;
    int n,m; char s1[N],s2[N];
    int f[2][N],h[2][N];
    signed main() {
        gs(s1+1),gs(s2+1); R l1=strlen(s1+1)-1,l2=strlen(s2+1)-1;
        R c=0; for(R i=0;i<=l2;++i) h[c][i]=1;
        for(R i=1;i<=l1;++i) {
            c^=1; h[c][0]=1;
            for(R j=1;j<=l2;++j) {
                h[c][j]=0;
                f[c][j]=max(f[c^1][j],f[c][j-1]);
                if(s1[i]==s2[j]) f[c][j]=max(f[c][j],f[c^1][j-1]+1);
                if(f[c][j]==f[c^1][j]) h[c][j]+=h[c^1][j];
                if(f[c][j]==f[c][j-1]) h[c][j]+=h[c][j-1];
                if(s1[i]==s2[j]&&f[c][j]==f[c^1][j-1]+1) h[c][j]+=h[c^1][j-1];
                if(s1[i]!=s2[j]&&f[c][j]==f[c^1][j-1]) h[c][j]-=h[c^1][j-1];
                h[c][j]=(h[c][j]+M)%M;
            }
        } printf("%d
    %d
    ",f[c][l2],h[c][l2]);
    }

    2019.07.11

  • 相关阅读:
    C. Karen and Game
    BZOJ2134: 单选错位
    BZOJ3562: [SHOI2014]神奇化合物
    BZOJ1084: [SCOI2005]最大子矩阵
    BZOJ5039: [Jsoi2014]序列维护
    BZOJ1798: [Ahoi2009]Seq 维护序列seq
    BZOJ3932: [CQOI2015]任务查询系统
    BZOJ3339: Rmq Problem
    BZOJ3585: mex
    BZOJ4196: [Noi2015]软件包管理器
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11170734.html
Copyright © 2020-2023  润新知