贪心算法的理解及例题分析

1、什么是贪心算法

贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解,虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的。

贪心算法总是做出在当前看来最好的选择。也就是贪心算法并不从整体最优上加以考虑,它所做出的选择只是某种意义上的局部最优选择。在一些情况下,即使贪心算法不能得到整体最优解,但其最终结果却是最优解的很好的近似解。

2、贪心算法的基本要素

(1)贪心选择性质

所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择达到。它也是贪心算法与动态规划算法的主要区别。

(2)最优子结构性质

当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。

3、贪心算法与动态规划算法的差异

参考资料:https://blog.csdn.net/u012110719/article/details/41928721

4、汽车加油问题的贪心选择性质

(1)汽车加油问题:

一辆汽车加满油后可行驶 n公里。旅途中有若干个加油站。设计一个有效算法,指出应 在哪些加油站停靠加油,使沿途加油次数最少。 

输入格式:第一行有 2 个正整数n和 k(k<=1000 ),表示汽车加满油后可行驶n公里,且旅途中有 k个加油站。 第二行有 k+1 个整数,表示第 k 个加油站与第k-1 个加油站之间的距离。 第 0 个加油站表示出发地,汽车已加满油。 第 k+1 个加油站表示目的地。

输出格式:输出最少加油次数。如果无法到达目的地,则输出“No Solution!”。

输入样例:

7 7

1 2 3 4 5 1 6 6

输出样例:

4

(2)汽车加油问题的贪心选择性质:

本道题的贪心选择性质是在行驶到下一个加油站之前,判断当前所剩的油量是否能支撑汽车到达下一个加油站,如果能,那么汽车不加油,反之,汽车加油。

该题设在加满油后可行驶的N千米这段路程上任取两个加油站a和b,且a距离始点比b距离始点近,则若在b加油不能到达终点那么在a加油一定不能到达终点,因为m+N<n+N,即在b点加油可行驶的路程比在a点加油可行驶的路程要长n-m千米,所以只要终点不在b、c之间且在c的右边的话,根据贪心选择,为使加油次数最少就会选择距离加满油得点远一些的加油站去加油,因此,加油次数最少满足贪心选择性质。 

(3)具体代码:

 1 #include <iostream>
 2 using namespace std;
 3 void Times(int n, int k, int l[])
 4 {
 5     int flag=1; // 设置flag判断汽车是否可以到达目的地
 6     int total=0; // 表示汽车行驶过路程
 7     int times=0; // 表示加油的次数
 8     for(int i=0;i<=k;i++) {
 9         if(n < l[i]) {
10             flag=0; // 当flag为0时,说明无法到达目的地
11             break;
12         }
13         total = total + l[i]; 
14         if(total > n) { // 当汽车行驶路程大于汽油量时,需要加油
15             total = 0;
16             i = i-1;
17             times++;
18         }
19     }
20     if(flag==0) cout<<"No Solution!";
21     else cout<<times;
22 }
23 
24 int main()
25 {
26     int n,k;
27     int length[1001];
28     cin>>n>>k;
29     for(int i=0;i<=k;i++) {
30         cin>>length[i];
31     }
32     Times(n,k,length);
33     return 0;
34 } 

5、贪心算法学习中遇到的问题及结对编程情况

 一开始学习贪心算法时,感觉和动态规划算法区别不是很大,做题之后发现两者之间还是有一些不同的。

posted @ 2018-12-02 19:37  打死也不吃香菜  阅读(3851)  评论(0编辑  收藏  举报