• BZOJ2457 [BeiJing2011]双端队列 【贪心】


    题目

       Sherry现在碰到了一个棘手的问题,有N个整数需要排序。
       Sherry手头能用的工具就是若干个双端队列。
    

    她需要依次处理这N个数,对于每个数,Sherry能做以下两件事:
    1.新建一个双端队列,并将当前数作为这个队列中的唯一的数;
    2.将当前数放入已有的队列的头之前或者尾之后。

    对所有的数处理完成之后,Sherry将这些队列排序后就可以得到一个非降的序列。

    输入格式

    第一行包含一个整数N,表示整数的个数。接下来的N行每行包含一个整数Di,其中Di表示所需处理的整数。

    输出格式

    其中只包含一行,为Sherry最少需要的双端队列数。

    输入样例

    6

    3

    6

    0

    9

    6

    3

    输出样例

    2

    提示

    100%的数据中N≤200000。

    题解

    由于最后排序的连续性,双端队列中元素的添加在最终排序中一定是连续的
    所以我们在一个双端队列中加入一个元素后,那么其仅可以向次小或次大方向扩展

    我们将位置按数值大小排序,显然每个低谷的地方是一段中最先出现的位置,这个位置先加入双端队列,然后就可以顺序向两端扩展

    但是大小相同的元素可以互换位置

    问题就转化为了:可以移动一些区间内的元素位置,求波谷最小的序列

    贪心取每个区间最大最小讨论一下

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
    using namespace std;
    const int maxn = 200005,maxm = 100005,INF = 0x7fffffff;
    inline int read(){
    	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 << 3) + (out << 1) + c - 48; c = getchar();}
    	return out * flag;
    }
    int A[maxn],id[maxn],n;
    inline bool cmp(const LL& a,const LL& b){return A[a] < A[b];}
    int main(){
    	n = read();
    	if (!n) {puts("0"); return 0;}
    	for (int i = 1; i <= n; i++) A[i] = read(),id[i] = i;
    	sort(id + 1,id + 1 + n,cmp);
    	int way = 0,ans = 1,last = INF;
    	for (int i = 1; i <= n; i++){
    		int r = i,mx = id[i],mn = id[i];
    		while (r < n && A[id[r + 1]] == A[id[r]]){
    			r++;
    			mx = max(mx,id[r]);
    			mn = min(mn,id[r]);
    		}
    		i = r;
    		if (!way){
    			if (mx < last) last = mn;
    			else last = mx,way = 1;
    		}else {
    			if (mn > last) last = mx;
    			else last = mn,way = 0,ans++;
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    装黑苹果遇到的术语
    关于Android方法数量限制的问题
    使用LeakCanary遇到的问题 就是不弹出来
    Android内存泄露自动检测神器LeakCanary
    Android开发常见的Activity中内存泄漏及解决办法
    LeakCanary 中文使用说明
    LeakCanary: 让内存泄露无所遁形
    LeakCanary——直白的展现Android中的内存泄露
    【腾讯Bugly干货分享】Android内存优化总结&实践
    Java基础--定时任务Timer
  • 原文地址:https://www.cnblogs.com/Mychael/p/8544878.html
Copyright © 2020-2023  润新知