[BZOJ2457] [BeiJing2011] 雙端佇列 [貪心][構造]
阿新 • • 發佈:2018-12-20
考慮到一個雙端佇列,先放的是中間某一個權值, 然後往左新增的數權值單調不遞增,往右新增的數權值單調不遞減。 容易發現往左新增、往右新增都一定要比一開始新增的晚,而且越靠近兩端越晚。 考慮按照權值排序,顯然只有位置↘↗的區間會被選到最後的雙端佇列裡 在實現的時候對相同數的處理比較麻煩。 不過其實也還好,相鄰相同縮點就行了。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cctype>
using namespace std;
int n, t, ans, m, tail = 0x3f3f3f3f;
bool cond;
pair<int, int> a[200005];
int Mx[200005];
int Mn[200005];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &t);
a[i] = make_pair(t,i);
}
sort(a+1, a+1+n);
Mn[++m] = a[1].second;
for (int i = 2 ; i <= n; ++i) {
if (a[i].first == a[i-1].first) continue;
Mx[m] = a[i-1].second;
Mn[++m] = a[i].second;
} Mx[m] = a[n].second;
for (int i = 1; i <= m; ++i) {
if (cond) {
if (tail > Mx[i]) tail = Mn[i];
else tail = Mx[i], cond = 0;
} else {
if (tail < Mn[i]) tail = Mx[ i];
else tail = Mn[i], cond = 1, ++ans;
}
}
printf("%d", ans);
return 0;
}