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;
}

 

posted @ 2018-10-24 01:35  Gloid  阅读(139)  评论(0编辑  收藏  举报