zoukankan      html  css  js  c++  java
  • BZOJ2457 BeiJing2011 双端队列

    【问题描述】 

     Sherry现在碰到了一个棘手的问题,有N个整数需要排序。

     Sherry手头能用的工具就是若干个双端队列。
          
    她需要依次处理这N个数,对于每个数,Sherry能做以下两件事:
    1.新建一个双端队列,并将当前数作为这个队列中的唯一的数;
    2.将当前数放入已有的队列的头之前或者尾之后。
     
    对所有的数处理完成之后,Sherry将这些队列排序后就可以得到一个非降的序列。
     
    【问题分析】
      加粗的字...必须要看清啊!!
      因为将队列排序就可以得到一个有序的序列,所以:1.队列中是有序的 2.队列之间也是有序的
      所以如果我们事先将所有数排好序,那么每个队列都是其中的一个连续的子部分,所有的队列一起组成了整个有序的序列。
      那么一个子部分要能放进队列有什么要求呢?
      
      我们在给数排序的时候,一定要带着它原来的标号走,是吧?[明显原来的顺序很重要!]
      那么我们划分的时候,这些标号一定要满足先减小再增加才能放在一个双端队列里,即必须按顺序由队列的中间往两边放。
      不然就会堵住?...脑洞一下就好...
      然后任务就是将一个序列划分成尽量少的先减小再增加的序列[这不是直接贪心+模拟么.....]
      
      当然还有特殊情况——相等的数。
      相等的数显然可以放在一个队列中....因为我可以控制其递增或递减,于是只需要记录最大值和最小值,然后当成一个整体就好。
      
      贪心+模拟的时候:
      
    [配合代码看就更清楚咯...]
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 
     5 using namespace std;
     6 
     7 const int maxn=200010;
     8 
     9 struct Node{
    10     int x,pos;
    11 }a[maxn];
    12 
    13 int n,cnt,ans;
    14 int Max[maxn],Min[maxn];
    15 
    16 bool cmp(const Node &A,const Node &B){
    17     if(A.x!=B.x) return A.x<B.x;
    18     return A.pos<B.pos;
    19 }
    20 
    21 int main(){
    22 #ifndef ONLINE_JUDGE
    23     freopen("2457.in","r",stdin);
    24 #endif
    25     scanf("%d",&n);
    26     for(int i=1;i<=n;i++)
    27         scanf("%d",&a[i].x),a[i].pos=i;
    28     sort(a+1,a+n+1,cmp);
    29     
    30     for(int i=1;i<=n;i++)
    31          if(a[i].x!=a[i-1].x || i==1){
    32                Max[cnt]=a[i-1].pos;
    33                Min[++cnt]=a[i].pos;
    34          }
    35     Max[cnt]=a[n].pos;
    36     
    37     int h=0x3f3f3f3f;bool b=true;
    38     //h表示当前链末尾的 pos大小 ,b表示当前链是向上或者向下趋势。 
    39     for(int i=1;i<=cnt;i++)
    40         if(!b){
    41             if(h>Max[i]) h=Min[i];
    42             else h=Max[i],b=true;
    43         }
    44         else{
    45             if(h<Min[i]) h=Max[i];
    46             else ans++,h=Min[i],b=false;
    47         }
    48     
    49     printf("%d",ans);
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    Ubuntu 下安装QT
    Ubuntu下配置Samba服务器
    二进制、八进制、十进制、十六进制之间转换
    Oracle_创建和管理表
    Oracle_数据处理
    单例模式
    01.DesignParttern设计模式,简单工厂,工厂方法,抽象工厂三大工厂的区别与联系
    MAC系统中的轻量级图像浏览器Lyn1.9
    MAC系统的绝佳截图工具Snipaste
    MAC系统的绝佳截图工具Snipaste
  • 原文地址:https://www.cnblogs.com/Robert-Yuan/p/4865779.html
Copyright © 2011-2022 走看看