1 概念

贪心的意思在于在作出选择时,每次都要选择对自身最为有利的结果,保证自身利益的最大化。贪心算法就是利用这种贪心思想而得出一种算法。

贪心算法作为五大算法之一,在数据结构中的应用十分广泛。例如:在求最小生成树的 Prim 算法中,挑选的顶点是候选边中权值最小的边的一个端点。在 Kruskal 算法中,每次选取权值最小的边加入集合。在构造霍夫曼树的过程中也是每次选择最小权值的节点构造二叉树。这种每次在执行子问题的求解时,总是选择当前最优的情形,恰好符合贪心的含义。

贪心算法可以简单描述为:大事化小,小事化了。对于一个较大的问题,通过找到与子问题的重叠,把复杂的问题划分为多个小问题。并且对于每个子问题的解进行选择,找出最优值,进行处理,再找出最优值,再处理。也就是说贪心算法是一种在每一步选择中都采取在当前状态下最好或最优的选择,从而希望得到结果是最好或最优的算法。

贪心算法在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。

2 算法流程

  (1)建立数学模型来描述问题。
  (2)把求解的问题分成若干个子问题。
  (3)对每一子问题求解,得到子问题的局部最优解。
  (4)把子问题的局部最优解合成原来问题的一个解。

3 伪代码

从问题的某一初始解出发
    while (能朝给定总目标前进一步) 
        do
            选择当前最优解作为可行解的一个解元素;
    由所有解元素组合成问题的一个可行解。

4 示例

题目描述:

小明手中有 1,5,10,50,100 五种面额的纸币,每种纸币对应张数分别为 5,2,2,3,5 张。若小明需要支付 456 元,则需要多少张纸币?

题目分析

(1)建立数学模型
  设小明每次选择纸币面额为 Xi ,需要的纸币张数为 n 张,剩余待支付金额为 V ,则有:
X1 + X2 + … + Xn = 456.
(2)问题拆分为子问题
  小明选择纸币进行支付的过程,可以划分为n个子问题:即每个子问题对应为:
在未超过456的前提下,在剩余的纸币中选择一张纸币。
(3)制定贪心策略,求解子问题

制定的贪心策略为:在允许的条件下选择面额最大的纸币。则整个求解过程如下:

  • 选取面值为 100 的纸币,则 X1 = 100, V = 456 - 100 = 356;

  • 继续选取面值为 100 的纸币,则 X2 = 100, V = 356 - 100 = 256;

  • 继续选取面值为 100 的纸币,则 X3 = 100, V = 256 - 100 = 156;

  • 继续选取面值为 100 的纸币,则 X4 = 100, V = 156 - 100 = 56;

  • 选取面值为 50 的纸币,则 X5 = 50, V = 56 - 50 = 6;

  • 选取面值为 5 的纸币,则 X6 = 5, V = 6 - 5 = 1;

  • 选取面值为 1 的纸币,则 X7 = 1, V = 1 - 1 = 0;求解结束

(4)将所有解元素合并为原问题的解

小明需要支付的纸币张数为 7 张,其中面值 100 元的 4 张,50 元 1 张,5 元 1 张,1 元 1 张。

代码实现

const int N = 5
int Count[N] = {5,2,2,3,5};//每一张纸币的数量 
int Value[N] = {1,5,10,50,100};
int solve(int money) {
    int num = 0;
    for(int i = N-1;i>=0;i--) {
        int c = min(money/Value[i],Count[i]);//每一个所需要的张数 
        money = money-c*Value[i];
        num += c;//总张数 
    }
    if(money>0) num=-1;
    return num;
}



©著作权归作者所有:来自51CTO博客作者mb5fe18fab305a5的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 趣味算法图解,高清无码图免费下载
  2. 扫雷与算法:如何随机化的布雷(一)
  3. 动画:什么是 BF 算法 ?
  4. 看《长安十二时辰》可以了解哪些算法知识
  5. 动画:七分钟理解什么是KMP算法
  6. 推荐一个项目:数据结构和算法必知必会的 50 个代码实现
  7. 这道算法题太简单?你忽略了时间复杂度的要求!
  8. 几道和「二叉树」有关的算法面试题
  9. 两分钟看完一道数学思想的算法题

随机推荐

  1. 等待执行所有ajax回调的最佳解决方案
  2. AngularJs location.path没有传递参数
  3. « VS 2010 和 .NET 4.0 系列之《VS 2010
  4. 在多个文件中需要相同的模块
  5. 获取JavaScript数组元素的最大长度
  6. AJAX内容更改加上小变化效果
  7. 利用javascript动态加载头部出现点击事件
  8. 即使在向上滚动时,AngularJS无限滚动调用
  9. CJL.0.1.min.js 的是一个什么JS库
  10. JS实现60s倒计时(亲测有效),及span标签如