• 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;
    	}
    
  • 相关阅读:
    iBatis——自动生成DAO层接口提供操作函数(详解)
    【Spring Boot项目】Win7+JDK8+Tomcat8环境下的War包部署
    MySQL使用小记
    DB迁移:从SQL Server 2005到MySQL
    【文章学习】监控网页卡顿、崩溃
    为什么执行x in range(y)如此之快
    python笔试题(三)
    python笔试题(二)
    python笔试题(-)
    rest-framework(2)
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9832304.html
Copyright © 2020-2023  润新知