寻找“最美”,贪心算法,我全都要

——算法第四章总结 软三 杨伟耿 20181003083

一、 以小见大,贪心策略

 

贪心算法总是做出在当前看来是最好的选择,贪心算法并不从整体最优上加以考虑,所做的选择只是在某种意义上的局部最优,当然我们也希望得到的最终结果也是整体最优的。在我看来,就是一个找“最”的过程,比如按最大排序、最小排序、平均最大等等。解体思路大致是,先寻找一个“最”,然后思考能否找出反例来推翻这个“最”,有反例的话就重新找“最”,直到可以通过反证法等证明该“最”是最优选择,且不存在反例。

 

汽车加油问题:

汽车加油问题 (15 )

题目来源:王晓东《算法设计与分析》

一辆汽车加满油后可行驶 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

 

贪心选择性质:用一个变量sum记录用掉的汽油可行驶的公里数,当累加到超过最大公里数的时候就要加油,这时候用另一个变量记录次数。如果加油站距离太远(大于一次加油所能行驶的最远距离时,就无法到达,输出“No Solution!”)。

每次都尽可能得多行驶距离,不行就加油。

源代码如下:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 int main() {
 6 
 7     int n,k,a[1001];
 8 
 9     cin>>n>>k;
10 
11     for(int i = 0; i <= k; i++) {
12 
13         cin>>a[i];
14 
15     }
16 
17     if(a[k] > n) {
18 
19         cout<<"No Solution!"<<endl;
20 
21         return 0;
22 
23     }
24 
25     int sum = 0, p = 0;
26 
27     for(int i = 0; i <= k; i++) {
28 
29         sum += a[i];
30 
31         if(sum > n) {
32 
33             p++;
34 
35             sum = a[i];
36 
37         }
38 
39     }
40 
41     cout<<p<<endl;
42 
43     return 0;
44 
45 }

 

 

二、 结对编程,查漏补缺

贪心算法较为简单,需要一起讨论解题思路的情况较少,但很多打代码的细节和优化需要一起思考。结对编程也是一个查漏补缺的过程,两个人可以互相看出对方在解题过程中的不足和缺点,可以互相指出和互相学习更正。

第四章重点是找到局部最优,并证明是题目的整体最优选择。难点在于代码实现,相对于解题思路的得出来说。

posted on 2019-11-24 16:02  mikasawell  阅读(175)  评论(0编辑  收藏  举报