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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章