BZOJ 动态规划 4300: 绝世好题

By Bartholomew


题意:

给我们一个 a 序列,让我们找出来一个 最长的 a[] 的子序列,使得b[i] &b[i1] != 0 ib 数组的长度!

样例:

input:
3
1 2 3
output:
2

分析:

1.O(n2 ) 暴力

DP 方程:
dp[i] = max(dp[k]) +1k<i 而且 a[k] & a[i]!=0

2.标算

那么我们注意到,在转移的时候 , 我们只是发现了 如果 a[i]的第j 位是1 的话,我们肯定是找 第 j 位也是 1 的 数字去转移喽!于是我们就知道怎么做了1

#pragma GCC optimize(3)
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <ctime>
#define N 100005
#define INF 0x3f3f3f3f 
using namespace std;
namespace FastIO
{
    inline int read()
    {
        int x=0;
        char c=getchar();
        bool flag=0;
        while(c<'0'||c>'9'){if(c=='-')flag=1;   c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
        return flag?-x:x;
    }
    inline int lowbit(int x) {return x & (-x) ; }
    inline int getmax(int x,int y){return (x<y)?y:x;}
    inline int getmin(int x,int y){return (x<y)?x:y;}
}
using namespace FastIO;
#define MAXN 32
int x,n,ans,ansx,f[MAXN];
int main(int argc, char const *argv[])
{   
    n = read(); 
    for(;n;--n)
    {
        x = read(); ansx = 0;
        for(int i=0;i<MAXN;i++) 
            if(x & (1<<i)) ansx = getmax(ansx,f[i]+1);
        for(int i=0;i<MAXN;i++)
            if(x & (1<<i)) f[i] = getmax(f[i],ansx);
        ans = getmax(ans,ansx);
    }
    printf("%d\n",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章