Fork me on GitHub

数据结构与算法——五个常规算法之四 · 贪心算法

贪婪算法(贪心算法)是指在对问题进行求解时,在每一步选择中都采取最好或者最优(即最有 利)的选择,从而希望能够导致结果是最好或者最优的算法。

下面案例,假设有如下课程,希望尽可能多的将课程安排在一间教室里:

课程 开始时间 结束时间
美术 9:00  10:00
英语 9:30  10:30
数学 10:00 11:00
计算机 10:30 11:30
音乐 11:00 12:00

 

 

 

 

 

 

 

这个问题看似要思考很多,实际上算法很简单: 

1. 选择结束最早的课,便是要在这教室上课的第一节课

2. 接下来,选择第一堂课结束后才开始的课,并且结束最早的课,这将是第二节在教室上的 课。

重复这样做就能找出答案,这边的选择策略便是结束最早且和上一节课不冲突的课进行排序, 因为每次都选择结束最早的,所以留给后面的时间也就越多,自然就能排下越多的课了。

每一节课的选择都是策略内的局部最优解(留给后面的时间最多),所以最终的结果也是近似最 优解(这个案例上就是最优解)。

贪婪算法所得到的结果往往不是最优的结果(有时候会是最优解),但是都是相对近似(接近)最 优解的结果。

贪婪算法并没有固定的算法解决框架,算法的关键是贪婪策略的选择,根据不同的问题选择 不同的策略。

 

基本思路 其基本的解题思路为:

  • 建立数学模型来描述问题
  • 把求解的问题分成若干个子问题
  • 对每一子问题求解,得到子问题的局部最优解
  • 把子问题对应的局部最优解合成原来整个问题的一个近似最优解

 

钱币找零问题:

假设1元、2元、5元、10元、20元、50元、100元的纸币分别有c0,c1,c2,c3,c4,c5,c6 张。现在要用这些钱来支付K元。至少要用多少张纸币?

 

解题思路:

用贪心算法的思想,很显然,每一步尽可能用面值大的纸币即可。在日常生活中我们自然而然也是这么做的。在程序中已经事先将Value按照从大到小的顺序排好。

 

代码如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 #define N 7
 5 
 6 //int value[N]={1, 2, 5, 10, 20, 50, 100}; //800
 7 //int count[N]={10, 2, 3, 1 ,2 ,3 , 5};
 8 int value[N]={1, 2, 5, 10, 20, 50, 100}; //800
 9 int count[N]={0, 0, 0, 0 ,3 ,1 , 0};
10 
11 /**************************
12 *对输入的零钱数,找到至少要用的纸币的数量
13 *参数:
14 * money - 要找/支付的零钱数
15 *返回:
16 * 至少要用的纸币的数量,-1 表示找不开
17 *************************/
18 
19 int solve(int money)
20 {
21     int num = 0;
22     int i = 0;
23     for(i=N-1; i>=0; i--)
24     {
25         int j = money/value[i]; //120 100 1 220 100 2
26         int c = j>count[i]?count[i]:j;
27         printf("需要用面值 %d 的纸币 %d 张\n", value[i], c);
28         money -= c*value[i];
29         num += c;
30         if(money==0) break;
31     }
32     if(money > 0) num = -1;
33     return num;
34 }
35 
36 int main(void)
37 {
38     int money = 0;
39     int num = 0;
40     printf("请输入要支付的零的数目:\n");
41     scanf_s("%d", &money);
42     num = solve(money);
43     
44     if(num==-1)
45     {
46         printf("对不起,找不开\n");
47     }
48     else 
49     {
50         printf("成功的使用至少%d 张纸币实现找零/支付!\n", num);
51     }
52     
53     system("pause");
54     return 0;
55 }

 

posted @ 2020-12-10 22:51  索智源  阅读(151)  评论(0编辑  收藏  举报