第四章实验报告

1.删数问题代码实现:

#include <iostream>
#include <string>

using namespace std;

string deleteDigits(string num, int k) {
    int n = num.size();

    // 循环删除k个数字
    for (int i = 0; i < k; ++i) {
        int j = 0;

        // 从左到右遍历,找到第一个比下一位大的数字并删除它
        while (j < num.size() - 1 && num[j] <= num[j + 1]) {
            ++j;
        }

        num.erase(j, 1);
    }

    // 去除前导0
    int start = 0;
    while (start < num.size() - 1 && num[start] == '0') {
        ++start;
    }

    return num.substr(start);
}

int main() {
    string num;
    int k;

    cin >> num;
    cin >> k;

    cout << deleteDigits(num, k) << endl;

    return 0;
}
反证法证明:

假设存在一个最优解,它不包含贪心选择。这意味着在最优解中,存在一个位置i,使得a[i] > a[i+1],但我们没有删除a[i],而是选择了删除另一个数字a[j],其中j > i

根据贪心策略,我们应该删除a[i],因为它比它后面的数字大,删除它会得到一个更小的数。但是根据假设,我们没有这样做。

现在,让我们交换删除操作:我们将a[j]放回原位,并删除a[i]。由于a[i] > a[i+1],删除a[i]后,新的数字序列在位置i的数字将会变小或者保持不变。同时,由于我们没有改变其他位置的数字,新数字序列仍然是一个有效的解,并且它满足删除了k个数字的条件。

由于新数字序列在位置i的数字变小了,而其他位置的数字没有变化,我们可以得出结论,新数字序列比原来的最优解更小。这与原假设的最优解相矛盾。

因此,我们的假设不成立,最优解必须包含贪心选择。这证明了删数问题的算法满足贪心选择性质。

对贪心算法的体会和思考:

1.贪心算法的核心在于通过一系列局部最优的选择来构造全局最优解。然而,并不是所有问题都能通过局部最优得到全局最优。
2.贪心算法通常实现简单,运行效率高,因为它不需要考虑所有可能的解决方案,只需做出当前最好的选择。
3.贪心算法的一个特点是它一旦做出选择,就不会回溯,即不会改变之前的决策。
4.贪心算法并不适用于所有问题。例如,对于需要考虑所有可能组合的问题(如旅行商问题),贪心算法往往不能得到最优解。
5.贪心算法与动态规划是两种常见的算法策略。动态规划通过考虑所有可能的子问题来找到最优解,而贪心算法只考虑当前的最优选择。在某些问题上,两者可以相互转换。
6.在实际应用中,有时即使贪心算法不能保证最优解,但若其解足够接近最优解,且计算效率高,那么贪心算法仍然是一个很好的选择。
7.设计一个有效的贪心算法通常需要深入理解问题的本质,以及如何定义“局部最优”。选择合适的贪心策略是算法成功的关键。
8.在一些复杂问题中,贪心算法可以与其他算法结合使用。例如,在动态规划算法中,贪心策略可以用来优化某些步骤,或者作为初始解来加速算法的收敛。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值