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;
}
时间: 2024-11-08 08:24:48

UVA 11491 Erasing and Winning 奖品的价值 (贪心)的相关文章

【思路、优化】UVa 11491 - Erasing and Winning

Juliano is a fan of the TV show Erasing and Winning, where participants are selected in a draw and receive money for taking part in the show. In the show, the presenter writes a number of N digits in a board. The participant must then erase exactly D

UVA 11491 Erasing and Winning

#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1

uva 11491:Erasing and Winning(贪心)

题意:给一个长n(n<10^5)位的数,删除d位,求删除后最大的数.(原数无前导0) 思路:从前往后扫,如果a[i] > a[i-1],则删除a[i-1].我暴力的用链表实现了…… #include <cstdio> #include <cstring> #include <cstdlib> #include <list> using namespace std; #define N 100020 char str[N]; int main()

UVa 11491 Erasing and Winning 题解

难度:α 用时:30 min 题目:?? 这是个裸贪心题. 题目要求在某数字字符串中删去给定个数的字符,使剩下来的数字最大. 那么不难想到用队列.线性复杂度.0 ms. 每读入一个数,就把之前比较小的拿掉. 注意不能拿太多,否则长度不够. 队满了也不能继续放.(除非有更大的元素可以把队尾的怼下去) 1 for (int i = 0; i < d; i++) { 2 char c = getchar(); 3 while (it > 0 && ans[it] < c &am

11491 - Erasing and Winning(贪心)

一开始真的没想到这竟然是一道贪心题目.  不过后来仔细想想也就明白了. 我采取的做法是自前向后扫一遍,用一个指针rear动态维护答案数组中的最后一个元素,如果遇到一个比它大的数s[i],那么从它开始将它及其它之前的比s[i]小的数全部删除,并且用变量cnt记录删除的个数, 防止删除多了. 对于贪心算法的正确性我们不难用反证法来证明: 假设这样做不是最优的,那么如果不这样做,对于一个长度一定的答案,得到的结果一定小于这样做的结果. 但是还有可能少删了,也就是第三组样例那种情况,所以我们贪心结束后要

UVA11491 奖品的价值

奖品的价值C804 运行时间限制:1000ms: 运行空间限制:51200KB 试题描述 你是一个电视节目的获奖嘉宾.主持人在黑板上写出一个 n 位非负整数(不以 0 开头),邀请你删除其中的 d 个数字,剩下的整数便是你所得到的奖品的价值.当然,你希望这个奖品价值尽量大.1<=d<=n<=10^5 输入 两行,第一行仅包含一个正整数d,第二行位一个符合题目要求的 n 位数. 输出 一个数,未奖品价值的最大值. 输入示例 4 23987921 输出示例 9921 很像万恶的小奥...(小

uva11491 奖品的价值(贪心)

uva11491 奖品的价值(贪心) 给你一个n位的整数,请你删除其中的d个数字,使得整数尽可能大.1<=d<n<=1e5. 首先因为前面的数位更重要,所以从左往右将每一位数字加入栈中.如果它比栈顶的大,就把栈顶的删掉,因为这样数肯定更大.如果删满了d个,就不再弹出栈顶了.如果全部扫完都删不满d个,只需舍弃最后的数位,使被删的数达到d即可. #include <cstdio> #include <cstring> using namespace std; cons

UVA LA 7146 2014上海亚洲赛(贪心)

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=648&problem=5158&mosmsg=Submission+received+with+ID+1708713 /** UVA LA 7146 2014上海亚洲赛(贪心) 题目大意:给定敌我双方士兵的数量和每个士兵的攻击力和防守力,如果两个士兵对战,一方

UVa 11491 奖品的价值

https://vjudge.net/problem/UVA-11491 题意:一个n位整数,删除其中的d个数字,输出最大值. 思路:肯定从高位开始分析,代码如下. 1 #include<string> 2 #include<iostream> 3 using namespace std; 4 5 const int maxn = 100000 + 5; 6 7 int n, d; 8 char a[maxn]; 9 10 int main() 11 { 12 //freopen(