浏览器标题切换
浏览器标题切换end
把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

[BZOJ 4300]绝世好题 dp

Description

给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=len)。

Input

输入文件共2行。
第一行包括一个整数n。
第二行包括n个整数,第i个整数表示ai。

Output

输出文件共一行。
包括一个整数,表示子序列bi的最长长度。

Sample Input

3
1 2 3

Sample Output

2

HINT

n<=100000,ai<=2*10^9

Solution

做法:按位$dp$

首先明确:&的运算规则是都为$1$才是$1$

所以两个数只要有一位上,都有一个有$1$,那么&后的结果就不会是$0$(位运算互不影响)

直接按这个思路去$dp$就可以了

因为是子序列,所以$dp$数组直接按位开就好了

#include <bits/stdc++.h>

using namespace std ;

#define N 100010

int n , ans ;
int a[ N ] , f[ 40 ] ;

int main() {
    scanf( "%d" , &n ) ;
    for( int i = 1 ; i <= n ; i ++ ) scanf( "%d" , &a[ i ] ) ;
    for( int i = 1 ; i <= n ; i ++ ) {
        int tmp = 0 ;
        for( int j = 0 ; j <= 30 ; j ++ ) {
            if( a[ i ] & ( 1 << j ) ) tmp = max( tmp , f[ j ] + 1 ) ;
        }
        for( int j = 0 ; j <= 30 ; j ++ ) {
            if( a[ i ] & ( 1 << j ) ) f[ j ] = tmp ;
        }
        ans = max( ans , tmp ) ;
    }
    printf( "%d\n" , ans ) ;
} 

 

 
posted @ 2018-10-01 22:48  henry_y  阅读(114)  评论(0编辑  收藏  举报