题意:给你一个n位整数,让你删掉d个数字,剩下的数字要尽量大。
题解:因为最后数字位数是确定的,而且低位数字对答案的贡献是一定不及高位数字的,所以优先选择选最大且最靠左边的数字,但是有一个限制,选完这个数字以后右边剩下的数字要保证足够接下来的选择,所以想到了优先队列,记录一个信息,选的数字所在的位置,以及上一个数字所在的位置,如果当前出队的数字在上一个选的位置前面就直接丢掉,每次选完一个以后剩下要选的数字就减少了,满足限制的条件的数字会增加,再把新的待选数字加入队列。
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5+5; struct dig { int val,pos; bool operator < (const dig & rhs) const { return val < rhs.val || (val == rhs.val && pos > rhs.pos); } }D[maxn]; priority_queue<dig> q; int n,d; void sovle() { while(q.size()) q.pop(); int i; for(i = 0; i <= d; i++) { q.push(D[i]); } int Need = n-d,pre = -1; while(Need){ while(q.top().pos<pre) q.pop(); const dig &u = q.top(); if(u.pos == n-Need) { for(i = u.pos; i < n; i++) printf("%d",D[i].val); break; } pre = u.pos; printf("%d",u.val); Need--; q.pop(); q.push(D[i++]); } putchar(' '); } int main() { // freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&d),n){ for(int i = 0; i < n; i++){ scanf("%1d",&D[i].val); D[i].pos = i; } sovle(); } return 0; }