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

    P4310 绝世好题

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

    说明
    对于100%的数据,1<=n<=100000,ai<=10^9。


    错误日志: 没搞清 每一位的dp值如何更新记录数组


    Solution

    一个数 (a) 可以接在数 (b) 后面, 当他们在二进制下有相同位同为 (1) 时成立
    这启发我们可以这样更新: 对于新的数 (x) 的每个 (1) 位,向前寻找一个最长的数为前一个转移
    可这样复杂度任然无法保证
    而想想又发现, 不优值一定不考虑, 我们只用对每一位含 (1) 位 保存最大长度即可

    我们设置一个数组 (ton[j]) 表示到目前为止, 二进制下第 (j) 位为 (1) 的最长长度
    更新第 (i) 个数 (x) 时, 当 (x) 的第 (j) 位为 (1) 时, 有 (dp[i] = max(dp[i], ton[j] + 1))
    更新完答案后需要返回来更新 (ton[j]), 当 (x) 的第 (j) 位为 (1) 时, 有 (ton[j] = max(ton[j], dp[i]))

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #define LL long long
    #define REP(i, x, y) for(int i = (x);i <= (y);i++)
    using namespace std;
    int RD(){
        int out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const int maxn = 200019;
    int num;
    int dp[maxn], ton[39];
    int ans;
    int main(){
    	num = RD();
    	REP(i, 1, num){
    		int x = RD();
    		REP(j, 1, 31){
    			int w = x >> (j - 1);
    			if(w & 1)dp[i] = max(dp[i], ton[j] + 1);
    			}
    		REP(j, 1, 31){
    			int w = x >> (j - 1);
    			if(w & 1)ton[j] = max(ton[j], dp[i]);
    			}
    		ans = max(ans, dp[i]);
    		}
    	printf("%d
    ", ans);
    	return 0;
    	}
    
  • 相关阅读:
    二叉树还原【前序+中序】【后续+中序】
    字符串中字符的个数和字符序列
    URL中“#” “?” &“”号的作用
    【java】String类和StringBuffer类常用操作
    Java基本开发环境搭建
    LeetCode:Pow(x, n)
    使用DX绘制3D物体时新手常犯错误,看不见物体时可以一一排查
    zlib代码生成
    zlib用法说明
    进程间通信的WM_COPYDATA的使用
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9832304.html
Copyright © 2011-2022 走看看