P4310 绝世好题 | DP 题解

题面传送门: P4310 绝世好题


第一眼以为是套路n2 dp, 一看数据范围1e5,直接懵逼5min(

其实挺简单的,题目也不错

题解

  仔细想想挺简单的, 因为b[i]&b[i-1]>0,那至少有一位二进制位b[i]和b[i-1]均为1。然后我们考虑枚举bi的每一位二进制1,在所有这一位也为1的数中, 取以该数结尾长度最长的作为上一位。

  不难想到, 可以用一个数组储存某位二进制位为i的数中,以它结尾的序列最大长度。

  说的有点复杂, 其实看代码应该更好理解。

 

code

  

 1 #include <iostream>
 2 #include <cstdio>
 3 #define ll long long
 4 using namespace std;
 5 
 6 const int N = 100005;
 7 int n, f[35], ans=0; 
 8 
 9 
10 int main(){
11     scanf("%d", &n);
12     for(int i=1; i<=n; i++){
13         int len = 0, t;
14         scanf("%d", &t);
15         
16         //找到最大长度 
17         for(int j=0; j<=30; j++)
18             if((t>>j)&1) len = max(len, f[j]);
19             
20         ans = max(ans, ++len);
21         //更新f数组 
22         for(int j=0; j<=30; j++)
23             if((t>>j)&1) f[j] = len;
24     } 
25     printf("%d", ans);
26     return 0;
27 }

 

posted @ 2020-11-25 21:19  ltdJcoder  阅读(79)  评论(1编辑  收藏  举报