1. 程式人生 > >[BZOJ2457][BeiJing2011]雙端佇列 (單調性)

[BZOJ2457][BeiJing2011]雙端佇列 (單調性)

正如lyd所說,和資料結構本身沒什麼太大關聯

題意

中文題面

  Sherry現在碰到了一個棘手的問題,有N個整數需要排序。        Sherry手頭能用的工具就是若干個雙端佇列。        她需要依次處理這N個數,對於每個數,Sherry能做以下兩件事: 1.新建一個雙端佇列,並將當前數作為這個佇列中的唯一的數; 2.將當前數放入已有的佇列的頭之前或者尾之後。   對所有的數處理完成之後,Sherry將這些佇列排序後就可以得到一個非降的序列。   求Sherry最少需要的雙端佇列數。

思路

反方向思考

先排序好,原來的位置跟著排序

要滿足雙端佇列,需要滿足排序之後的原位置要先遞減,再遞增

不滿足的話開新的雙端佇列

程式碼

 
#include<cstdio>
#include<algorithm>
#include<vector>
#define N 200005
#define INF 0x3fffffff
using namespace std;
int n;
pair<int, int>a[N];
vector<int>p[N];
int main()
{
    scanf("%d
", &n); for (int i = 1; i <= n; i++) { scanf("%d", &a[i].first); a[i].second = i; } sort(a + 1, a + 1 + n); int t = 0; for (int i = 1; i <= n; i++) { p[++t].push_back(a[i].second); while (a[i].first == a[i + 1].first) p[t].push_back(a[++i].second); }
for (int i = 1; i <= t; i++) sort(p[i].begin(), p[i].end()); bool flag = 0; int num = INF, ans = 1; for (int i = 1; i <= t; i++) { int s = p[i].size(); if (flag) { if (num < p[i][0]) num = p[i][s - 1]; else { ++ans; flag = 0; num = p[i][0]; } } else { if (num > p[i][s - 1]) num = p[i][0]; else { flag = 1; num = p[i][s - 1]; } } } printf("%d\n", ans); return 0; }