zoukankan      html  css  js  c++  java
  • BZOJ4300: 绝世好题(dp)

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 2751  Solved: 1493
    [Submit][Status][Discuss]

    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


    Source

    题目简洁好评

    $n^2$的dp比较无脑,但是肯定过不了

    刚开始我以为这玩意儿有决策单调性,但是很显然是错的。。

    正解充分利用了$&$的性质,我们直接用$f[i]$表示第$i$位不为$0$时的最大值

    转移的时候枚举这一位是不是$0$就可以了

    #include<cstdio>
    #include<algorithm>
    #define int long long 
    using namespace std;
    const int MAXN = 1e5 + 10;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    int a[MAXN], f[33], B = 32;
    main() {
        int N = read(), out = 0;
        for(int i = 1; i <= N; i++) a[i] = read();
        for(int i = 1; i <= N; i++) {
            int ans = 0;
            for(int j = B; j >= 0; j--) 
                if(a[i] & (1 << j))
                    ans = max(ans, f[j] + 1);
            for(int j = B; j >= 0; j--)
                if(a[i] & (1 << j))
                    f[j] = ans;
        }
        for(int i = 0; i <= B; i++) 
            out = max(out, f[i]);
        printf("%d", out);
    }
  • 相关阅读:
    java四种线程池类型以及可选择的阻塞队列
    复习-java向上转型
    synchronized 加在方法和代码块底层实现区别
    synchronized 和 lock 的区别
    hashmap-put方法过程
    mybatis-防止sql注入
    synchronized-粗略过程
    消息队列-观察者模式和发布订阅模式区别
    复习-进程的调度算法
    Chocolatey
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9225604.html
Copyright © 2011-2022 走看看