• HDU 4604 Deque 二分最长上升子序列


    题目大意就是给一个deque

    然后有n个数,依次进行操作,每种操作,你可以把这个数放在deque首部,也可以放在尾部,也可以扔掉不管,但是要保证deque中的数是非递减的。最要求deque中最长能是多少


    思路是这样的:对于这个序列,最重要的应该是第一个进去的数是什么,然后以该数为开头的最长不升子序列和以该数为开头的最长不降子序列则可以凑成一个最长的序列,当然这两个序列中可能都出现了该数,也就是发生了重复,所以就要减掉重复的部分,即两个子序列中有该数个数较少的序列中这个数应当被减掉。

    然后由于数据量大,所以要用到二分求最长上升子序列的方法

    顺便使用了stl中的equal_range函数,意思就是返回一个区间[it1,it2) 然后区间内的数都是要查找的那个数。  这就使得我们计算序列中有多少个某个数时提供了方便。


    开两种数组,一种是以当前某数为开头的不降 /不增序列的最大长度,一种是某数在这不降/不升 序列中出现的次数。

    然后倒着求,这样到了某数时,就知道以它开头的不降/不增序列的最大长度。

    最后枚举一遍进deque的第一个数即可

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <map>
    #include <queue>
    #include <set>
    #include <vector>
    #define MAXM 111111
    #define MAXN 111111
    #define INF 1000000007
    #define eps 1e-8
    using namespace std;
    typedef vector<int>::iterator Viter;
    int n;
    vector<int>g;
    int a[MAXN];
    int dp1[MAXN], dp2[MAXN], num1[MAXN], num2[MAXN];
    void gao(int dp[], int num[])
    {
        g.clear();
        Viter it;
        for(int i = n - 1; i >= 0; i--)
        {
            int sz = g.size();
            if(!sz || a[i] >= g[sz - 1])
            {
                g.push_back(a[i]);
                dp[i] = sz + 1;
            }
            else
            {
                it = upper_bound(g.begin(), g.end(), a[i]);
                dp[i] = it - g.begin() + 1;
                *it = a[i];
            }
            pair<Viter, Viter>bounds = equal_range(g.begin(), g.end(), a[i]);
            num[i] = bounds.second - bounds.first;
        }
    }
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d", &n);
            for(int i = 0; i < n; i++) scanf("%d", &a[i]);
            gao(dp1, num1);
            for(int i = 0; i < n; i++) a[i] = -a[i];
            gao(dp2, num2);
            int ans = 0;
            for(int i = 0; i < n; i++)
                ans = max(ans, dp1[i] + dp2[i] - min(num1[i], num2[i]));
            printf("%d
    ", ans);
        }
        return 0;
    }
    


  • 相关阅读:
    使用PHP建立GIF
    无数据库的详细域名查询程序PHP版
    用PHP实现通过Web执行C/C 程序
    判断一数是否在一已知数组中的函数
    如何将本地项目上传到码云
    IIS服务器,IIS日志文件占用C盘空间,C盘空间不足 常见问题
    谈谈个人能力的系统性
    毕业后5年决定命运
    个人取得工资、薪金所得应当如何缴纳个人所得税
    Chart 控件 for vs2008的安装
  • 原文地址:https://www.cnblogs.com/riskyer/p/3233706.html
Copyright © 2020-2023  润新知