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