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

                
            
        
浙公网安备 33010602011771号