贪心算法(删数问题)

数学原理:

从第一个数开始遍历,到找到单调递减的第一个数(即单调递增的最后一个数),则删除,若无单调递减子序列,则删掉最后一个非递减序列的数;每找到一个就又从头开始。即每做一次删数,就是一次贪心选择,删掉此数剩下的数为组成最小,经过证明,此结论正确。

eg:

42135

单调递减的第一个数为第一个数为4,删掉得到2135

之后单调递减的第一个数为2,删掉得到135

不存在单调递减序列,则删除最后一个数5

需要注意的是:2001删除一个数后应该为1,而不是001,需要进行处理

#include <algorithm>
#include <iostream>
​
using namespace std;
​
int shanshu(string &a, int k);
int main() {
    string st;
    int n, startIndex = 0;
    cin >> st >> n;
    n = shanshu(st, n);
    for (int i = 0; i < n; i++) {
        if (st[i] == '0') {
            startIndex++;
        }
    }
    for (int i = startIndex; i < n; i++) {
        cout << st[i];
    }
​
    return 0;
}
int shanshu(string &a, int k) {
    int n = a.size(), j = 0;
    while (k > 0) {
        for (int i = 0; i < n; i++) {
            if (a[i] > a[i + 1]) {
                for (int j = i; j < n; j++) {
                    a[j] = a[j + 1];
                }
                n--;
                break;  // 忘记退出循环了
            } else if (i == n - 1) {
                n--;
                break;
            }
        }
        k--;
    }
    return n;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值