[BZOJ2457][BeiJing2011]雙端佇列 (單調性)
阿新 • • 發佈:2018-12-22
正如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; }