贪心算法(Greedy Algorithm)故事版本

🎭 故事名:《现实主义者小贪的财富冒险》


🧭 背景设定:

在遥远的计算国中,有一位名叫 小贪 的商人。他不是那种喜欢深思熟虑的人,也不爱做复杂的计划。他有一个信条:

“我只选眼前看起来最划算的那一笔买卖。”

于是他背上行囊,踏上旅程,去寻找“最快发财”的方法。

🧠 这正是 贪心算法的核心思想

  • 每一步都选择当前最优解

  • 不回头考虑之前的决策

  • 期望通过一系列局部最优解达到全局最优


🛒 第一幕:初入市场,快速交易

小贪来到第一个村庄,看到市场上有三种商品可以买卖:

商品成本价卖出价利润
苹果¥2¥5+¥3
香蕉¥3¥6+¥3
橘子¥4¥7+¥3

他没有犹豫:“哪个利润高就买哪个!”但三个都一样……

🧠 对应代码逻辑:

 选择最大利润的商品 = max(苹果, 香蕉, 橘子)

虽然没赚最多,但他节省了时间!


🕰️ 第二幕:时间有限,效率第一

小贪继续前行,来到了一个限时集市。这里每种商品都有交易时间限制,他只能选几样。

他看了看,发现:

商品时间收益
A1h¥100
B2h¥180
C3h¥240

他想:“我要尽可能在最短时间内赚最多的钱。”于是选择了 A → B → C。

🧠 对应贪心策略:

  • 按照单位时间收益排序(A:100/h,B:90/h,C:80/h)

  • 优先选择单位收益高的商品

这就是经典的 活动选择问题 / 区间调度问题


💰 第三幕:金币兑换,贪心失效

来到王城,小贪遇到了一个新的挑战:用最少的硬币支付某个金额。

当前货币系统是:[1, 5, 10, 25](美分制)

他要支付 30 分钱,怎么选?

他立刻选了:1个 25 分 + 1个 5 分 → 只需两枚硬币 ✅ 这正是贪心策略成功的例子。

🧠 但在某些货币体系下会失败,比如:

  • 硬币面额为 [1, 3, 4]

  • 目标金额为 6

贪心法:4 + 1 + 1 → 3 枚 最优解:3 + 3 → 2 枚 ❌

🧠 所以说:贪心不一定总是正确的


📈 第四幕:股票交易,贪心显神威

小贪听说股市能赚钱,便决定研究一下。

他看到价格走势如下:

 [7, 1, 5, 3, 6, 4]

他决定:“只要今天比昨天便宜,我就买;只要明天涨了,我就卖。” 于是他在第2天买入(1元),第3天卖出(5元),第4天再买入(3元),第5天卖出(6元)。总共赚了:4 + 3 = 7元!

🧠 对应 LeetCode 股票 II 题目:

 for (int i = 1; i < prices.size(); ++i) {
     if (prices[i] > prices[i - 1]) {
         profit += prices[i] - prices[i - 1];
     }
 }

✨ 第五幕:最终总结

小贪回顾自己的旅程,得出结论:

  • 在很多情况下,贪心策略确实能让他快速做出决策;

  • 有时候还能得到最优解;

  • 但也有不少时候,它并不准确;

  • 但它最大的优点是:快!省时间!

🧠 所以贪心适用于:

  • 活动选择问题(如会议安排)

  • 区间调度问题(如任务分配)

  • 哈夫曼编码(压缩算法)

  • 背包问题的近似解

  • 股票交易最大化收益(无限次交易)


🧠 总结:现实主义者视角 vs 程序员视角

商人视角程序员视角
选择眼前最划算的买卖每一步取当前最优解
不回头思考以前的选择不进行回溯或记忆化
有时赚得多,有时亏点局部最优不一定等于全局最优
快速做决策时间复杂度低,常为 O(n log n) 或 O(n)

✅ 示例代码(LeetCode 122. 买卖股票的最佳时机 II):

 #include <iostream>
 #include <vector>
 using namespace std;
 ​
 int maxProfit(vector<int>& prices) {
     int profit = 0;
     for (int i = 1; i < prices.size(); ++i) {
         if (prices[i] > prices[i - 1]) {
             profit += prices[i] - prices[i - 1];
         }
     }
     return profit;
 }
 ​
 int main() {
     vector<int> prices = {7, 1, 5, 3, 6, 4};
     cout << "最大收益:" << maxProfit(prices) << endl;
     return 0;
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值