UVA 11491 Erasing and Winning 奖品的价值 (贪心)

题意:给你一个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('\n');
}


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

 

posted @ 2015-08-03 11:26  陈瑞宇  阅读(636)  评论(0编辑  收藏  举报