CF keks(单调队列)

Problem K. Keks
Input le: stdin
Output le: stdout
Time limit: 2 seconds
Memory limit: 256 megabytes
Mirko and Slavko are bored at math class again so they came up with new game. Mirko writes down an
N digit number, and Slavko's task is to obtain the largest possible number after having removed exactly
K digits.
Help him do that!
Input
The rst line of input contains integers N and K (1  K < N  500 000).
The following line contains N digit number. This number starts with non-zero digit.
Output
The rst and only line of output should contain the largest possible number Slavko can obtain by removing
K digits from the given number.
Example
stdin stdout
4 2
1924
94
7 3
1231234
3234
10 4
4177252841
775841

给一个长为n的数,删掉k位数,求最大值。贪心,尽量使目前的最高位大,维护一个k,代表当前还能删除的个数,然后每次考察区间长为k+1的数,找到其中的最大值最靠前的位置,那么删掉这个位置前的数,下次考察的区间从这个位置的后面一个开始。直接暴力找最值是超时的,可以用单调队列或优先队列优化。

#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#include<iostream>
using namespace std;
typedef pair<char,int> P;
const int maxn = 500000 + 5;

priority_queue<P> Q;
char s[maxn];
vector<char> ans;

int main(){
    int n,k;
    while(scanf("%d%d",&n,&k) != EOF){
        scanf("%s",s);
        int K = k;
        while(!Q.empty()) Q.pop();
        ans.clear();
        for(int i = 0;i < k+1;i++) Q.push(P(s[i],-i));
        ans.push_back(Q.top().first);
        int last = -Q.top().second+1;
        k -= last-1;
        for(int i = K+1;i < n;i++){
            Q.push(P(s[i],-i));
            while(-Q.top().second < last) Q.pop();
            char tem = Q.top().first;
            int id = -Q.top().second;
            ans.push_back(tem);
            last = id + 1;
            k -= id-last;
        }
        for(int i = 0;i < ans.size();i++) printf("%c",ans[i]);
        printf("\n");
    }
    return 0;
}


你可能感兴趣的:(CF keks(单调队列))