bzoj2423: [HAOI2010]最长公共子序列
唉我还是太弱了,还在想什么KMP和SA,其实这个就是DP而已。。。
嗯套用网上大佬的说法,第一问DP简单想。。那第二问维护一个G数组表示方案数,注意去重和滚动就行。
#include<cstdio> #include<iostream> #include<cstring> using namespace std; const int mod=100000000; char sa[5100],sb[5100]; int f[2][5100],g[2][5100]; int main() { scanf("%s",sa+1);int n=strlen(sa+1);n--; scanf("%s",sb+1);int m=strlen(sb+1);m--; int now=0; memset(f,0,sizeof(f)); memset(g,0,sizeof(g));g[0][0]=1; for(int j=0;j<=m;j++)g[1][j]=1; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(sa[i]==sb[j]) { f[now][j]=f[1-now][j-1]+1; g[now][j]=g[1-now][j-1]; if(f[now][j]==f[1-now][j])g[now][j]=(g[now][j]+g[1-now][j])%mod; if(f[now][j]==f[now][j-1])g[now][j]=(g[now][j]+g[now][j-1])%mod; } else { f[now][j]=max(f[1-now][j],f[now][j-1]); g[now][j]=0; if(f[now][j]==f[now][j-1])g[now][j]=(g[now][j]+g[now][j-1])%mod; if(f[now][j]==f[1-now][j])g[now][j]=(g[now][j]+g[1-now][j])%mod; if(f[now][j]==f[1-now][j-1])g[now][j]=(g[now][j]+mod-g[1-now][j-1])%mod; } } now=1-now; } printf("%d\n%d\n",f[1-now][m],g[1-now][m]); return 0; }
pain and happy in the cruel world.