BZOJ 4300: 绝世好题

Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 2767 Solved: 1501
[Submit][Status][Discuss]
Description
给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=len)。

Input
输入文件共2行。
第一行包括一个整数n。
第二行包括n个整数,第i个整数表示ai。

Output
输出文件共一行。
包括一个整数,表示子序列bi的最长长度。

Sample Input
3

1 2 3
Sample Output
2
HINT

n<=100000,ai<=2*10^9

解题思路

90分做法,直接按最长上升子序列的思路dp,数据好像比较水,LUOGU上可以拿90。
100分做法,跟上面那个完全没有关系,发现每一个数都可以用它二进制意义下的各位数来更新,所以设dp[i]为二进制第i位等于1时的最大值。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
const int MAXN = 100005;

inline int rd(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
    return x*f;
}

int ans,n;
int dp[35];

int main(){
    n=rd();
    for(register int i=1;i<=n;i++){
        int x=rd();
        int mx=0;
        for(register int j=0;j<=30;j++) 
            if((1<<j)&x && dp[j]>mx) mx=dp[j];
        mx++;
        for(register int j=0;j<=30;j++)
            if((1<<j)&x) {
                dp[j]=mx;
                if(dp[j]>ans) ans=dp[j];
            }
    }
    printf("%d",ans);
} 
posted @ 2018-07-04 18:09  Monster_Qi  阅读(127)  评论(0编辑  收藏  举报