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

    题目

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

    输入格式

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

    输出格式

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

    输入样例

    3

    1 2 3

    输出样例

    2

    提示

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

    题解

    按位dp
    f[i] = max{f[j] + 1} (存在A[i]二进制某位和A[j]同时为1)
    这样做是O(n2)
    我们可以将二进制每一位为1时的最优答案储存下来,就可以做到O(32n)的复杂度

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    using namespace std;
    const int maxn = 100005,maxm = 100005,INF = 1000000000;
    inline int RD(){
        int out = 0,flag = 1; char c = getchar();
        while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
        while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
        return out * flag;
    }
    int n,A[maxn][40],f[maxn],mx[40];
    int main(){
        n = RD(); int x;
        REP(i,n){
            x = RD(); f[i] = 1;
            for (int j = 1; x; j++,x >>= 1){
                if (A[i][j] = (x & 1)){
                    f[i] = max(f[i],mx[j] + 1);
                }
            }
            for (int j = 1; j <= 32; j++)
                if (A[i][j])
                    mx[j] = max(mx[j],f[i]);
        }
        int Ans = 0;
        REP(i,32) Ans = max(Ans,mx[i]);
        printf("%d
    ",Ans);
        return 0;
    }
    
  • 相关阅读:
    【JDK】JDK源码分析-LinkedList
    【JDK】JDK源码-Queue, Deque
    【JDK】JDK源码分析-Vector
    【JDK】JDK源码分析-ArrayList
    Jmeter-安装及配置(一)
    数据库连接池技术
    2017年度总结
    Windows重装系统
    Java + Selenium + Appium手机自动化测试
    DbVisualizer出现下列错误:Could not read XML file
  • 原文地址:https://www.cnblogs.com/Mychael/p/8282710.html
Copyright © 2011-2022 走看看