高明的最长公共子序列
国家集训队论文。?
https://wenku.baidu.com/view/ed99e4f77c1cfad6195fa776.html
XJOI题 重复串。 虽然不满的1000^3复杂度能水过,但还是学了一下。。
以后压位别压太死了(用unsigned压32位这种),可能会引出很多麻烦,比如自然溢出之类的。。
放代码。
1 #include <bits/stdc++.h> 2 #define U unsigned 3 #define ll long long 4 const U h=2147483648; 5 using namespace std; 6 U g[26][34],u[34],X[34],H[32]; 7 int n,o,mx,f[65536]; char S[1005]; 8 int main(){ 9 scanf("%d%s",&n,S+1); 10 H[0]=1; for (int i=1;i<32;++i) H[i]=H[i-1]<<1; 11 for (int i=1;i<65536;++i) f[i]=f[i>>1]+(i&1); 12 for (int I=1;I<=n;++I){ 13 memset(g,0,sizeof g); memset(u,0,sizeof u); 14 for (int i=I,j=0;i<=n;++i,++j) g[S[i]-'a'][j>>5]|=H[j&31]; 15 for (int k=1;k<I;++k){ 16 o=S[k]-'a'; 17 for (int i=0;i<34;++i) X[i]=u[i]|g[o][i]; 18 for (int i=33;~i;--i) u[i+1]|=(bool)(u[i]&h),u[i]<<=1; 19 u[0]|=1; o=n-I+2; X[o>>5]|=H[o&31]; 20 (u[o>>5]|=H[o&31])^=H[o&31]; 21 for (int i=0,j=0;i<34;++i) 22 if ((ll)X[i]<(ll)u[i]+j) u[i]=X[i]-u[i]-j,j=1; 23 else u[i]=X[i]-u[i]-j,j=0; 24 (u[o>>5]|=H[o&31])^=H[o&31]; 25 (X[o>>5]|=H[o&31])^=H[o&31]; 26 for (int i=0;i<34;++i) (u[i]^=X[i])&=X[i]; 27 } 28 o=0; 29 for (int i=0;i<34;++i) o+=f[u[i]&65535]+f[u[i]>>16]; 30 mx=max(mx,o); 31 } 32 printf("%d\n",n-mx*2); 33 return 0; 34 }
转载请标明出处 http://www.cnblogs.com/cyz666/