BZOJ 2457: [BeiJing2011]雙端隊列
阿新 • • 發佈:2017-10-22
貪心 sta gre submit algorithm data discus 相同 兩個
Submit: 338 Solved: 165
[Submit][Status][Discuss]
第一行包含一個整數N,表示整數的個數。接下來的N行每行包含一個整數Di,其中Di表示所需處理的整數。
6
3
6
0
9
6
3
2
2457: [BeiJing2011]雙端隊列
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 338 Solved: 165
[Submit][Status][Discuss]
Description
Sherry現在碰到了一個棘手的問題,有N個整數需要排序。 Sherry手頭能用的工具就是若幹個雙端隊列。 她需要依次處理這N個數,對於每個數,Sherry能做以下兩件事: 1.新建一個雙端隊列,並將當前數作為這個隊列中的唯一的數; 2.將當前數放入已有的隊列的頭之前或者尾之後。 對所有的數處理完成之後,Sherry將這些隊列排序後就可以得到一個非降的序列。Input
Output
其中只包含一行,為Sherry最少需要的雙端隊列數。Sample Input
6
3
6
0
9
6
3
Sample Output
2
HINT
100%的數據中N≤200000。
題解:
這個題目我們首先註意到題目所給的一個性質,就是要求兩個有序,即每個雙端隊列內部還要有有序,所以對於一個序列,我們排序一下,那麽每個雙端隊列一定取的是一個連續的區間。
所以我們以權值為第一關鍵字,編號為第二關鍵子排序,之後模擬反的過程,如果要一個雙端隊列和法,那麽他們所取的編號一定是先下降然後上升的,這樣我們貪心,每次的元素盡量放到一個雙端隊列裏,模擬一遍就可以了。(註意,如果元素相同,那麽他們顯然是可以放在一個隊列,所以一起處理就可以了)。
代碼:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <iostream> #define MAXN 200100 using namespace std; struct node{ int v,ps; }a[MAXN*2]; int n; int mx[MAXN],mi[MAXN],cnt=0; int ans=0,flag=1,now=1<<30; bool cmp(const node A,const node B){return A.v<B.v||(A.v==B.v&&A.ps<B.ps);} int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i].v),a[i].ps=i; sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++){ if(i==1||a[i].v!=a[i-1].v){ mx[cnt]=a[i-1].ps; mi[++cnt]=a[i].ps; } } mx[cnt]=a[n].ps; for(int i=1;i<=cnt;i++){ if(flag==0){ if(now>mx[i]) now=mi[i]; else now=mx[i],flag=1; } else{ if(now<mi[i]) now=mx[i]; else flag=0,now=mi[i],ans++; } } printf("%d\n",ans); return 0; }
BZOJ 2457: [BeiJing2011]雙端隊列