分析:
若设状态,f【i】表示以i结尾的最长序列的话,显然有n^2的转移方程,但会tle。结合位运算的性质,当前节点只能从它的二进制表示中某一位为1的状态转移而来(保证位与不等于0),所以可以把状态设为f【i】表示二进制下以第i位为1结尾的最长序列,那么当前a【i】的贡献是只会去更新它的二进制位上为1的位置的答案,然后再循环一下把a【i】为1的位置的答案跟新为能转移而来的最大值。
参考代码
#include<bits/stdc++.h>
using namespace std;
int f[31];
int main ()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n;cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
int w=0;
for(int j=0;j<=30;j++)
{
if((1<<j)&x){f[j]++;w=max(w,f[j]);}
}
for(int j=0;j<=30;j++)if((1<<j)&x)f[j]=w;
}
int ans=1;
for(int i=0;i<=30;i++)ans=max(ans,f[i]);
cout<<ans;
return 0;
}