zoukankan      html  css  js  c++  java
  • BZOJ4300 绝世好题

    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


    正解:按位DP

    解题报告:

      绝世好题!

      一眼秒,DP。然而我开始只想出了O(N^2)的算法,其实我们并不需要去枚举从谁转移过来,毕竟是和位运算有关,那么我们肯定是要从位的角度出发。

      f[i]表示处理到当前数,第i位不为0的最优长度。转移很好转。(开始有一个误区:认为一定这个序列的所有数某一位都不为0,实际并不是,因为相邻两个数可以是不同位置使得&运算不为0)

      代码如下:

     

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<algorithm>
     7 using namespace std;
     8 typedef long long LL;
     9 const int MAXN = 1000011;
    10 int n,a[MAXN],ans;
    11 int f[31];//f[i]表示第i位不为0的当前的长度最大值
    12 
    13 inline int getint(){
    14     int w=0,q=1;char c=getchar();
    15     while(c!='-' && (c<'0' || c>'9')) c=getchar();
    16     if(c=='-') q=-1,c=getchar();
    17     while(c>='0' && c<='9') w=w*10+c-'0',c=getchar();
    18     return w*q;
    19 }
    20 
    21 int main()
    22 {
    23     n=getint(); for(int i=1;i<=n;i++) a[i]=getint();
    24     int now;
    25     for(int i=1;i<=n;i++) {
    26     now=0;
    27     for(int j=0;j<=30;j++) if( (a[i] & (1<<j)) != 0 ) now=max(f[j],now);
    28     now++; for(int j=0;j<=30;j++) if( (a[i] & (1<<j)) != 0 ) f[j]=max(f[j],now);
    29     }
    30     for(int i=0;i<=30;i++) ans=max(ans,f[i]);
    31     printf("%d",ans);
    32     return 0;
    33 }
     
  • 相关阅读:
    Android资源列表
    GTD资源列表[070826更新] [GTD]
    Table显示滚动条
    html语言中的meta元素
    GridView分页的实现
    图解CSS的padding,margin,border属性
    javascript moveTo() 函数
    IE6 中的最大最小寬度和高度 css 高度 控制(兼容版本)
    enableEventValidation
    window.resizeTo()和window.open()
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5814135.html
Copyright © 2011-2022 走看看