题意:
给出一个长度为n的数组,求这个数组的子序列,其中包含1~k数字各一个,求这些子序列中字典序最小的一个。
思路: 应该尽量拿字典序小的那个。可以记录每个数字最后出现位置,然后就是单调栈的应用了
#include <stack>
#include <vector>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
const int N = 200010;
const int inf = 1e9 + 10;
int n, k, a[N], last[N], picked[N];
stack<int> s;
int main()
{
scanf("%d%d", &n, &k);
for(int i = 1;i <= n; ++ i) {
scanf("%d", &a[i]);
last[a[i]] = i;
}
for(int i = 1;i <= n; ++ i) {
if(picked[a[i]]) continue;
if(s.size() == 0 || (s.top() < a[i])) {
s.push(a[i]);
picked[a[i]] = 1;
} else {
while(s.size() && last[s.top()] > i && s.top() > a[i]) {
int top = s.top();
picked[top] = 0;
s.pop();
}
s.push(a[i]);
picked[a[i]] = 1;
}
}
vector<int> ans;
while(s.size()) ans.push_back(s.top()), s.pop();
for(int i = ans.size() - 1;i >= 0; -- i) printf("%d ", ans[i]);
return 0;
}
//3 2 1 3 1