bzoj 2423: [HAOI2010]最長公共子序列【dp+計數】
阿新 • • 發佈:2018-09-22
class pri ace 滾動數組 spa == i++ int const
設f[i][j]為a序列前i個字符和b序列前j個字符的最長公共子序列,轉移很好說就是f[i][j]=max(f[i-1][j],f[i][j-1],f[i-1][j-1]+(a[i]==b[j]))
設g[i][j]為a序列前i個字符和b序列前j個字符的最長公共子序列個數,這個轉移是轉移f的時候從前驅狀態長度相同的加起來即可
要滾動數組
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=5005,mod=100000000; int n,m,f[2][N],g[2][N]; char a[N],b[N]; int main() { scanf("%s%s",a+1,b+1); n=strlen(a+1)-1,m=strlen(b+1)-1; for(int i=0;i<=m;i++) g[0][i]=1; g[1][0]=1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(a[i]==b[j]) { f[i&1][j]=f[~i&1][j-1]+1; g[i&1][j]=g[~i&1][j-1]; if(f[i&1][j]==f[~i&1][j]) g[i&1][j]=(g[i&1][j]+g[~i&1][j])%mod; if(f[i&1][j]==f[i&1][j-1]) g[i&1][j]=(g[i&1][j]+g[i&1][j-1])%mod; } else { f[i&1][j]=max(f[~i&1][j],f[i&1][j-1]); g[i&1][j]=0; if(f[i&1][j]==f[~i&1][j-1]) g[i&1][j]=((g[i&1][j]-g[~i&1][j-1])%mod+mod)%mod; if(f[i&1][j]==f[~i&1][j]) g[i&1][j]=(g[i&1][j]+g[~i&1][j])%mod; if(f[i&1][j]==f[i&1][j-1]) g[i&1][j]=(g[i&1][j]+g[i&1][j-1])%mod; } } printf("%d\n%d\n",f[n&1][m],g[n&1][m]); return 0; }
bzoj 2423: [HAOI2010]最長公共子序列【dp+計數】