bzoj 4300: 绝世好题【dp】

设f[i][j]表示数列到i为止最后一项第j位为1的最大子序列长度,每次从i-1中1<<j&a[i]!=0的位+1转移来
然后i维是不需要的,答案直接在dp过程中去max即可

#include<iostream>
#include<cstdio>
using namespace std;
int n,f[35],ans;
int read()
{
	int r=0,f=1;
	char p=getchar();
	while(p>'9'||p<'0')
	{
		if(p=='-')
			f=-1;
		p=getchar();
	}
	while(p>='0'&&p<='9')
	{
		r=r*10+p-48;
		p=getchar();
	}
	return r*f;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
		int x=read(),k=1;
        for(int j=0;j<=30;j++)
			if((1<<j)&x) 
				k=max(f[j]+1,k);
        for(int j=0;j<=30;j++)
			if((1<<j)&x) 
				f[j]=max(f[j],k);
        ans=max(ans,k);
    }
    printf("%d\n",ans);
    return 0;
}
posted @ 2018-08-02 22:10  lokiii  阅读(95)  评论(0编辑  收藏  举报