1. 贪心算法简介
贪心算法(Greedy Algorithm)是一种基于贪心思想的算法策略。它通过每一步选择当前状态下最优的解决方案,从而逐步得到全局最优解。贪心算法通常在问题具有贪心选择性质和最优子结构性质时被应用。
贪心算法的基本思想是,每一步选择当前情况下看起来最好的解决方案,而不考虑之后可能发生的情况。它不进行回溯,也不考虑全局最优解,而是根据局部最优选择来构建解决方案。
适合贪心算法具有的特征:
1、优化问题。
2、问题的求解可以划分为若干阶段。
3、能够制定出最优量度标准。
4、问题具有最优子结构性质。
贪心算法的步骤通常如下:
1、确定问题的最优子结构:问题的最优解可以通过子问题的最优解来构建。
2、定义贪心选择策略:确定每一步的最优选择。
3、构建解决方案:根据贪心选择策略,逐步构建问题的解决方案。
4、验证解决方案:检查贪心算法得到的解决方案是否满足问题的要求。
2. 找零钱问题
关于贪心算法的一个经典例子是找零钱问题(Coin Change Problem)。问题描述如下:给定一些不同面额的硬币和一个需要找零的金额,找出最少的硬币数量来凑出该金额。利用贪心算法解决该问题的思路如下:
(1)输入找零的金额和每种硬币的面额;
(2)从币值从高到低进行贪心策略;
(3)选择所要表示的币值;
(4)记录所选择的币值所要的数目,现金值实时更改;
(5)输出结果。
算法实现
#include <iostream>
#include <vector>
#include <algorithm>
std::vector<int> greedyCoinChange(std::vector<int>& coins, int amount) {
std::vector<int> result;
// 按面额从大到小排序硬币
// std::sort(coins.begin(), coins.end(), std::greater<int>()); // 与下一行功能相同
std::sort(coins.rbegin(), coins.rend()); // c.rbegin() 返回一个逆序迭代器,它指向容器c的最后一个元素
for (auto coin : coins) {
while (amount >= coin) {
result.push_back(coin);
amount -= coin;
}
}
if (amount != 0) {
// 找不到合适的硬币组合
result.clear();
}
return result;
}
int main() {
std::vector<int> coins = { 1, 5, 10, 25 };
int amount = 47;
std::vector<int> result = greedyCoinChange(coins, amount);
if (!result.empty()) {
std::cout << "找零的硬币数量:" << result.size() << std::endl;
std::cout << "找零的硬币面额:";
for (auto coin : result) {
std::cout << coin << " ";
}
std::cout << std::endl;
} else {
std::cout << "无法找零。" << std::endl;
}
return 0;
}
在上述示例中,我们定义了一个greedyCoinChange函数,它接收一个硬币面额的向量coins和需要找零的金额amount。首先,我们将硬币面额按从大到小排序,以便每次选择最大面额的硬币。然后,我们循环遍历每个硬币,直到无法再选择该硬币为止。最后,如果剩余的金额不为0,则表示无法找零,返回空的结果。在main函数中,我们定义了一组硬币面额和需要找零的金额,并调用greedyCoinChange函数来获取找零的结果。如果结果不为空,我们输出找零的硬币数量和面额;否则,输出无法找零的信息。
例如,对于硬币面额为{1, 5, 10, 25},需要找零47的情况下,输出将会是:文章来源:https://www.toymoban.com/news/detail-507975.html
找零的硬币数量:5
找零的硬币面额:25 10 10 1 1
这表示我们可以用5个硬币凑出47的金额,其中包括1个25分硬币、2个10分硬币和2个1分硬币。文章来源地址https://www.toymoban.com/news/detail-507975.html
到了这里,关于算法设计与分析之贪心算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!