UVA - 11491 Erasing and Winning 贪心

该博客讨论了一道编程竞赛问题,要求在删除数字的条件下使剩余数字最大化。作者提出采用贪心策略,从高位开始选择,但最初的遍历方法会导致超时。改进策略是从低位向高位扫描,当遇到降序排列时停止删除,以减少扫描次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:给出一个n位数的数字,要求你删掉m位,使得最后的n-m位数达到最大

解题思路:贪心策略,肯定是最高位越大越好了。刚开始的思路是这样的,从前往后扫描,找到比当前位大的数,找到后,再往后继续扫描,看有没有比这个数更大的数,这样明显会超时的。

换种思路,什么情况下不用删除数字了,肯定是这个数的所有位是降序排序的时候,所以,我们改变策略,从后往前扫描,并标记,记录前一位的值,这样需要扫描的次数就会大大降低了

#include<cstdio>
#include<cstring>
#define maxn 100010
int mark[maxn];
char str[maxn];

int main() {
    int n, m;
    while(scanf("%d%d", &n, &m) == 2 && n + m) {
        scanf("%s", str);
        memset(mark,0,sizeof(mark));

        int cnt = 0;
        int pre = str[0], pre_pos = 0;
        for(int i = 1; i < n; i++) {
            if(!mark[i]) {
                if(str[i] > pre) {
                    for(int j = i - 1; j >= 0; j--) {
                        if(!mark[j] && str[j] < str[i] && cnt < m) {
                            mark[j] = 1;
                            cnt++;
                        }
                        if(!mark[j] && str[j] >= str[i])
                            break;
                    }
                }
                pre = str[i], pre_pos = i;
            }
        }

        if(cnt < m) {
            for(int i = n - 1; i >= 0 && cnt < m; i--)
                if(!mark[i]) {
                    mark[i] = 1;
                    cnt++;
                }
        }

        for(int i = 0; i < n; i++)
            if(!mark[i])
                printf("%c", str[i]);
        printf("\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值