1. 程式人生 > >[BZOJ 4300]絕世好題 dp

[BZOJ 4300]絕世好題 dp

一個 tput name sample 表示 its ++ 整數 define

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 ) ; }

[BZOJ 4300]絕世好題 dp