算法之贪心思想

这个贪心的行为在算法中也成为了一种指导思想,也就是说贪心算法所作出的选择在当时的环境下是最好的,说深一点就是它只是某种

意义上的局部最优解,但不一定是全局最优解,此时往往接近于最优解。

一: 优点

前面也说了,贪心只是求的当前环境下的最优解,而不是追究整体的最优解,所以贪心就避免了为求的整体最优解而枚举各种方案所

耗费的时间。

二: 问题

① 不能保证贪心所得出的解是整体最优的。

② 不能用来求最大解和最小解问题。

③ 只能求满足某些约束条件的可行解的范围。

三: 案例

其实说到贪心,基本上都会提到“背包问题”,这里我就举一个“找零钱的问题“,对的,找零钱问题是我们生活中一个活生生的贪心算法

的例子,比如我买了“康师傅来一桶方便面”,给了10两银子,方便面3.8两,那么收银mm该找我6.2两,现实中mm不自觉的就会用到贪心的行

为给我找最少张币,总不能我给mm一张,mm给我十几张,那样mm会心疼的。

此时mm提供的方案就是:5元1张,1元1张,2角1张。

 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5  6 namespace Tanxin 7 { 8     class Program 9     {10         static void Main(string[] args)11         {12             while (true)13             {14                 var money = Exchange(decimal.Parse(Console.ReadLine()));15 16                 Console.WriteLine("\n找给您的张数为:\n");17                 foreach (var single in money)18                 {19                     if (single.Value != 0)20                     {21                         Console.WriteLine("{0}元\t{1}张\n", single.Key, single.Value);22                     }23                 }24                 Console.WriteLine("--------------------------------------------------------------------");25             }26         }27 28         /// <summary>29 /// 找零30 /// </summary>31 /// <param name="num"></param>32         static Dictionary<decimal, int> Exchange(decimal num)33         {34             var money = GetInit();35 36             int i = 0;37 38             while (true)39             {40                 if (num < 0.05M)41                 {42                     return money;43                 }44 45                 var max = money.Keys.ElementAt(i);46 47                 if (num >= max)48                 {49                     num = num - max;50 51                     //money的张数自增52                     money[max] = money[max] + 1;53                 }54                 else55                 {56                     //如果是小于1毛,大于5分的情况下57                     if (num < 0.1M && num >= 0.05M)58                     {59                         //按一毛计算60                         money[0.10M] = money[0.10M] + 1;61 62                         num = 0.0M;63                     }64                     else65                     {66                         i++;67                     }68                 }69             }70         }71 72         static Dictionary<decimal, int> GetInit()73         {74             Dictionary<decimal, int> money = new Dictionary<decimal, int>();75 76             //key表示钱,value表示钱的张数77             money.Add(100.00M, 0);78             money.Add(50.00M, 0);79             money.Add(20.00M, 0);80             money.Add(10.00M, 0);81             money.Add(5.00M, 0);82             money.Add(2.00M, 0);83             money.Add(1.00M, 0);84             money.Add(0.50M, 0);85             money.Add(0.20M, 0);86             money.Add(0.10M, 0);87 88             return money;89         }90     }91 }

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-03 20:44:54

算法之贪心思想的相关文章

图论——关于Dijkstra的贪心思想

引语 作为求解最短路问题的算法中最稳健的算法,Dijkstra以其惊奇的操作和独特的魅力,吸引了无数OIer学习.钻研.身为一名蒟蒻,本人以有限的能力付诸仔细的思考,对于Dijkstra算法中贪心思想的正确性有了新的认识. 咳咳,相信我,这是一篇很正常的博客,本人也是一名很正常的博主. 大多数OIer在初学Dijkstra算法时都不求甚解,单纯的把板子背下来就算了,而对于其中的贪心思想的内涵并没有做过深入挖掘.对于其贪心算法的正确性,我以我个人的理解,进行非严格的证明,希望有助于大家理解Dijk

经典算法宝典——贪婪思想(五)(1)

贪婪法(Greedy)又叫登山法,它的根本思想是逐步到达山顶,即逐步获得最优解,是解决最优化问题时的一种简单但适用范围有限的策略."贪婪"可以理解为以逐步的局部最优,达到最终的全局最优. 贪婪算法没有固定的算法框架,算法设计的关键是贪婪策略的选择.一定要注意,选择的贪婪策略要具有无后向性,即某阶段状态一旦确定以后,不受这个状态以后的决策影响.也就是说某状态以后的过程不会影响以前的状态,只与当前状态有关,也称这种特性为无后效性.因此,适应用贪婪策略解决的问题类型较少,对所采用的贪婪策略一

Kruskal算法(贪心+并查集=最小生成树)

http://www.51nod.com/ Kruskal算法的高效实现需要一种称作并查集的结构.我们在这里不介绍并查集,只介绍Kruskal算法的基本思想和证明,实现留在以后讨论. Kruskal算法的过程: (1) 将全部边按照权值由小到大排序. (2) 按顺序(边权由小到大的顺序)考虑每条边,只要这条边和我们已经选择的边不构成圈,就保留这条边,否则放弃这条边. 算法 成功选择(n-1)条边后,形成一个棵最小生成树,当然如果算法无法选择出(n-1)条边,则说明原图不连通. 以下图为例: 边排

uva 10020- Minimal coverage (贪心思想 简单区间覆盖)

题目大意:给出一个范围M,然后给出若干的区间,以0 0 终止, 要求用最少的区间将0 ~M 覆盖,输出最少个数以及方案. 解题思路:典型的区间覆盖问题,算法竞赛入门经典P154上有讲. /*author: charkj_z */ /*time: 0.108s */ /*rank: 674 */ /*为什么不把没用的地方去掉? 因为去掉了我觉得不像我能写出来的*/ /*Ac code : */ #include<stdio.h> #include<string.h> #include

排序算法的基本思想和OC代码实现

算法的基本思想和OC代码实现 一 .冒泡排序   (平均时间复杂度 o(N*N))  基本思想:两个数比较大小,较大的数下沉,较小的数冒起来. 过程:比较相邻的两个数据,如果第二个数小,就交换位置 从后向前两两比较,一直到比较最前两个数据.最终最小数被交换到起始的位置,这样第一个最小数的位置就排好了. 继续重复上述过程,依次将第2,3,….,n-1个最小数排好位置. int arr[5]={23,21,45,23,64}; int temp; for (int i=0; i<4; i++) {

hdu 4105 贪心思想

淋漓尽致的贪心思想 波谷一定是一位数,波峰一位数不够大的时候添加到两位数就一定够大了的. 当在寻找波谷碰到零了就自然当成波谷. 当在寻找波峰时碰到零时,将前面的波谷加到前一个波峰上,让当前的零做波谷,使得波谷的值尽量小,这就是本题最关键的贪心思想,一直想不到. 代码中:a表示前一个值,b表示当前考虑的值,tag为偶数时表示正在寻找波谷,奇数时在寻找波峰. #include<iostream> #include<cstdio> #include<cstring> #inc

经典算法宝典——动态规划思想(六)(2)

1.01背包问题 有N件物品和一个容量为V的背包,第i件物品的体积是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大. 解析: 这是最基础的背包问题,特点是每种物品仅有一件,可以选择放或不放.用子问题定义状态,即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值.其状态转移方程便是f[i][v] = max{f[i-1][v], f[i-1][v-c[i]]+w[i]},这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的,所以有必要将它详细解

经典算法宝典——分治思想(四)(1)

分治法(Divide and Conquer)的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的几个相似问题,以便各个击破,分而治之. 说明: 分治策略的应用很广,具体表现形式各异,比如:折半查找.合并排序.快速排序.二叉树遍历(先遍历左子树再遍历右子树).二叉排序树的查找等算法. 一.分治算法框架 1.算法设计思想 分治法求解问题的过程是,将整个问题分解成若干个小问题后分而治之.如果分解得到的子问题相对来说还太大,则可反复使用分治策略将这些子问题分成更小的同类型子问题,直至产生出方

POJ 3253 Fence Repair 类似哈夫曼树的贪心思想

Fence Repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24550   Accepted: 7878 Description Farmer John wants to repair a small length of the fence around the pasture. He measures the fence and finds that he needs N (1 ≤ N ≤ 20,000)