BZOJ4300 绝世好题(动态规划)
设f[i][j]为前i个数中所选择的最后一个数在第j位上为1时的最长序列长度,转移显然。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 100010 int n,a[N],f[N][31]; int main() { #ifndef ONLINE_JUDGE freopen("bzoj4300.in","r",stdin); freopen("bzoj4300.out","w",stdout); const char LL[]="%I64d\n"; #else const char LL[]="%lld\n"; #endif n=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=1;i<=n;i++) { int x=0; for (int j=30;~j;j--) f[i][j]=f[i-1][j]; for (int j=30;~j;j--) if (a[i]&(1<<j)) x=max(x,f[i][j]); for (int j=30;~j;j--) if (a[i]&(1<<j)) f[i][j]=x+1; } int ans=0; for (int i=0;i<=30;i++) ans=max(ans,f[n][i]); cout<<ans; return 0; }