C++

贪心 [C++]

Marimo_z
2025-04-04 / 0 评论 / 3 阅读 / 正在检测是否收录...

一、贪心算法的核心思想

  1. 局部最优 → 全局最优
    在每一步选择中,仅考虑当前状态下最优的决策,不回溯或考虑未来步骤的影响。
  2. 无后效性
    一旦做出选择,不会再改变(不可逆)。
  3. 适用条件

    • 贪心选择性质:通过局部最优能推导全局最优。
    • 最优子结构:问题的最优解包含子问题的最优解。

二、贪心算法的实现步骤

  1. 分解问题
    将问题分解为多个子问题。
  2. 定义贪心策略
    确定每一步选择的最优标准。
  3. 证明策略的有效性
    确保局部最优能推导全局最优(通常通过数学归纳法)。
  4. 迭代求解
    逐步构建问题的解。

三、经典贪心算法问题

1. 找零钱问题

问题描述:用最少的硬币数凑出指定金额(假设硬币面额是标准倍数关系,如1,5,10,25)。

C++实现

#include <iostream>
#include <vector>
using namespace std;

vector<int> greedyCoinChange(int amount, vector<int>& coins) {
    vector<int> result;
    sort(coins.rbegin(), coins.rend()); // 降序排列
    for (int coin : coins) {
        while (amount >= coin) {
            result.push_back(coin);
            amount -= coin;
        }
    }
    return result;
}

int main() {
    vector<int> coins = {25, 10, 5, 1}; // 硬币面额
    int amount = 63;
    vector<int> res = greedyCoinChange(amount, coins);
    for (int c : res) cout << c << " "; // 输出:25 25 10 1 1 1 
    return 0;
}

2. 活动选择问题

问题描述:选择最多的互不重叠活动(按结束时间排序后,每次选最早结束的活动)。

C++实现

#include <vector>
#include <algorithm>
using namespace std;

struct Activity {
    int start, end;
};

int selectActivities(vector<Activity>& activities) {
    sort(activities.begin(), activities.end(), 
        [](const Activity& a, const Activity& b) { return a.end < b.end; });
    
    int count = 1, lastEnd = activities[0].end;
    for (int i = 1; i < activities.size(); i++) {
        if (activities[i].start >= lastEnd) {
            count++;
            lastEnd = activities[i].end;
        }
    }
    return count;
}

四、贪心算法的应用场景

  1. 霍夫曼编码:构造最优前缀码。
  2. 最小生成树:Prim算法和Kruskal算法。
  3. 最短路径:Dijkstra算法(无负权边时)。
  4. 任务调度:如作业调度、CPU任务调度。

五、贪心算法的优缺点

优点缺点
实现简单,运行高效(通常O(n)或O(n log n))不保证全局最优(需严格证明适用性)
适用于实时系统或大规模数据对问题条件要求严格

六、贪心 vs 动态规划

贪心算法动态规划
无后效性,仅依赖当前状态依赖子问题的历史状态
效率更高可能更通用,但复杂度更高
需要严格证明通过递推公式保证正确性

七、如何验证贪心策略?

  1. 数学归纳法:证明每一步的贪心选择能导向全局最优。
  2. 反证法:假设存在更优解,推导矛盾。
  3. 替换法:将贪心解与假设的最优解对比。

总结

贪心算法的核心在于通过局部最优的快速决策逼近全局最优,适用于满足特定条件的问题。在C++实现时,通常需要结合排序和迭代操作,重点在于策略的合理性和正确性证明。实际应用中需仔细分析问题是否满足贪心算法的前提条件。

0

评论 (0)

取消