1. 程式人生 > >[BZOJ2457] [BeiJing2011] 雙端佇列 [貪心][構造]

[BZOJ2457] [BeiJing2011] 雙端佇列 [貪心][構造]

考慮到一個雙端佇列,先放的是中間某一個權值, 然後往左新增的數權值單調不遞增,往右新增的數權值單調不遞減。 容易發現往左新增、往右新增都一定要比一開始新增的晚,而且越靠近兩端越晚。 考慮按照權值排序,顯然只有位置↘↗的區間會被選到最後的雙端佇列裡 在實現的時候對相同數的處理比較麻煩。 不過其實也還好,相鄰相同縮點就行了。

#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; }