重生之我在优快云学贪心算法

C++ 的贪心算法(Greedy Algorithm)是一种在每一步选择中都做出当前最优解(局部最优),希望最终能得到全局最优解的算法策略。贪心算法适用于最优子结构贪心选择性质的问题。


贪心算法的基本步骤

  1. 排序(若必要):根据贪心策略对数据进行排序。
  2. 贪心选择:在当前状态下选择最优解。
  3. 可行性检查(若必要):确保选择符合问题约束。
  4. 重复执行,直到所有选择完成。

C++ 贪心算法示例

示例 1:活动选择问题(区间调度问题)

问题描述:有 n 个活动,每个活动都有起始时间 start[i] 和结束时间 end[i],每次只能选择一个活动,求最多能安排多少个互不冲突的活动。

贪心策略:每次选择最早结束的活动,这样可以留给后面的活动更多的时间。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// 活动结构体
struct Activity {
    int start, end;
};

// 按结束时间排序
bool compare(Activity a, Activity b) {
    return a.end < b.end;
}

int maxActivities(vector<Activity> &activities) {
    sort(activities.begin(), activities.end(), compare); // 按结束时间排序
    int count = 1, last_end = activities[0].end;

    for (int i = 1; i < activities.size(); i++) {
        if (activities[i].start >= last_end) {  // 如果活动开始时间不冲突
            count++;
            last_end = activities[i].end;
        }
    }
    return count;
}

int main() {
    vector<Activity> activities = {{1, 3}, {2, 5}, {3, 9}, {6, 8}, {5, 7}};
    cout << "最多可以安排的活动数: " << maxActivities(activities) << endl;
    return 0;
}

时间复杂度:O(nlog⁡n)O(n \log n)(排序占主导)


示例 2:最小零钱找零

问题描述:给定若干面额的硬币,如何用最少的硬币找零 amount

贪心策略:优先使用面值最大的硬币。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int minCoins(vector<int> &coins, int amount) {
    sort(coins.rbegin(), coins.rend()); // 按面值从大到小排序
    int count = 0;

    for (int coin : coins) {
        while (amount >= coin) {
            amount -= coin;
            count++;
        }
    }
    return count;
}

int main() {
    vector<int> coins = {1, 5, 10, 25}; 
    int amount = 63;
    cout << "最少硬币数: " << minCoins(coins, amount) << endl;
    return 0;
}

注意:贪心算法不一定适用于所有找零问题,比如硬币面额 {1, 3, 4}6 时,贪心会选择 {4, 1, 1}(3枚),但最优解是 {3, 3}(2枚)。


贪心算法的适用场景

  1. 区间问题(活动安排、区间覆盖)
  2. 最小代价问题(Huffman 编码、最小生成树)
  3. 排序优化(最优任务调度)
  4. 贪心找零(但要小心无法保证全局最优)

总结:贪心算法在部分问题上能得到最优解,但不能保证所有问题都适用,使用前要确保满足贪心选择性最优子结构。&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值