前往:我自己搭建的博客
题目
题解
相邻两数位与不为0,等价于两数存在一个二进制位都为1。若只考虑某一个二进制位,则所有此位为1的数构成了最长子序列。再将所有二进制位综合考虑,使用动态规划。f[i]表示以上一个第i位为1的数为结尾的最长子序列的长度。若当前数的第i位为0,则不作更新;若为1,则选一个最大的f[j]更新。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6;
int n;
int f[32],a[maxn];
inline void dp()
{
for(int i=1;i<=n;i++)
{
int mx=0;
for(int j=0;j<=30;j++) if(a[i]&(1<<j)) mx=max(mx,f[j]+1);
for(int j=0;j<=30;j++) if(a[i]&(1<<j)) f[j]=mx;
}
}
int main()
{
scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]);
dp(); int ans=0;
for(int i=0;i<=30;i++) ans=max(ans,f[i]);
printf("%d\n",ans);
return 0;
}