题意
传送门 AcWing 134 双端队列
题解
队列拼接后得到非降序列,考虑将数组按照值域排序,求在索引值上满足单谷性质的连续不重叠的序列的最小值。单谷性质是为了保证新加入双端队列的数字只能从两头插入,即其索引值大于队内中间元素的索引值。
采取贪心策略,从左向右扫描数组,尽可能的拓展满足单谷性质的段的长度。若存在值域相等的元素,保证其相邻的条件下,可以交换其位置,使段尽可能的拓展;可以观察到使值域相等的元素按照索引值有序后,升序拼接或降序拼接,不会使答案更差。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200005;
struct node
{
int x, id;
} A[maxn];
int N;
bool cmp1(const node &a, const node &b) { return a.x < b.x; }
bool cmp2(const node &a, const node &b) { return a.id < b.id; }
int main()
{
scanf("%d", &N);
for (int i = 0; i < N; ++i)
{
scanf("%d", &A[i].x);
A[i].id = i;
}
sort(A, A + N, cmp1);
int s = -1, pre = 0, res = 0;
for (int i = 0; i < N;)
{
int l = i, r = i + 1, x = A[i].x;
while (r < N && A[r].x == x)
++r;
sort(A + l, A + r, cmp2);
int mn = A[l].id, mx = A[r - 1].id;
if (s == -1)
s = 0, pre = mn, ++res;
else if (s == 0)
{
if (mx > pre)
s = 1, pre = mx;
else
pre = mn;
}
else
{
if (mn < pre)
++res, s = 0, pre = mn;
else
pre = mx;
}
i = r;
}
printf("%d\n", res);
return 0;
}