zoukankan      html  css  js  c++  java
  • 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;
    }
    


  • 相关阅读:
    Java应用调优指南之-工具篇
    2016第18周四
    2016第18周三
    IE下JS接受ActiveX控件方法
    2016第18周一
    Jquery插件写法及extentd函数
    2016第17周六
    嘛:如何远视 还有遥远的未来
    寻找失踪的整数数组(Find the missing integer)
    Cocos2d-x 2地图步行实现:SPFA算法
  • 原文地址:https://www.cnblogs.com/riskyer/p/3233706.html
Copyright © 2011-2022 走看看