绝世好题-按位DP

n2暴力就不讲了。听人讲可以吸氧水过去。

这里考虑怎么优化这一个算法,

其实可以发现这个题唯一的限制就是要求满足a[i]&a[j]!=0。

那么我们可以想到,两个数只要有一位(二进制下)都是1,那么就是满足的。

所以我们对于每一个新的数,分别考虑它的二进制下的每一位,

如果那一位上是1,那么直接 接上之前的这一位上也为1的最长一段。

那么我们可以只存下这二进制下每一位为1时最长的值就OK了。

所以这就是按位DP??,我也不知道诶

#include <bits/stdc++.h>
using namespace std;
inline int gi () {
    int x=0,w=0; char ch=0;
    while (!(ch>='0' && ch<='9')) {if (ch=='-') w=1; ch=getchar ();}
    while (ch>='0' && ch<='9') x= (x<<3)+(x<<1)+(ch^48), ch=getchar ();
    return w?-x:x;
}

const int N=1e5+10;

int n,Ans,a[N],f[33];

inline int Max (int a, int b) {return a>b?a:b;}

int main ()
{
    n=gi ();
    for (int i=1;i<=n;++i) a[i]=gi ();
    for (int i=1,k;i<=n;++i) {
        k=1;
        for (int j=0;j<=30;++j)
            if ((1<<j)&a[i]) k=Max (k, f[j]+1);
        for (int j=0;j<=30;++j)
            if ((1<<j)&a[i]) f[j]=Max (f[j], k);
        Ans=Max (Ans, k);
    }
    printf ("%d
", Ans);
    return 0;
}
原文地址:https://www.cnblogs.com/Bhllx/p/9839225.html