贪心算法
一、对贪心算法的理解
贪心算法是通过一系列选择来得到问题的解,并不从整体最优的角度考虑,所做的选择只是在某种意义上的局部最优选择,因此贪心算法并不能解决所有所有的问题。
用贪心算法来解决的问题有两个性质:
1、贪心选择性质:所求问题的整体最优解可以通过一系列局部最优的选择。
2、最优子结构性质:一个问题的最优解包含其子问题的最优解。
与动态规划算法的区别在于,动态规划中每步所做选择依赖于其子问题的解,以自底向上的方式计算,而贪心算法仅作出当前状态下的最优解,再去解决作出这个选择后产生的相应的子问题,以自顶向下的方式计算。
二、选择一道作业题目说明你的算法满足贪心选择性质
题目:
人民币的面值有100、50、20、10、5、2、1元。请你输出找零纸币数最少的方案
输入格式:
两个整数,分别表示付款金额和消费金额
输出格式:
输入找零方案。包含若干行,每行包含两个数字,纸币面额和纸币数量
输入样例:
10 3
输出样例:
在这里给出相应的输出。例如:
5 1
2 1
代码:
1 #include <iostream> 2 using namespace std; 3 int money[7]={100,50,20,10,5,2,1}; 4 int ans[7]={0}; 5 6 int main() 7 { 8 int pay, coms; 9 cin >> pay >> coms; 10 11 int rest=pay-coms; 12 int i=0; 13 while(rest!=0) { 14 if(rest>=money[i]) { 15 ans[i]=rest/money[i]; 16 rest =rest-ans[i]*money[i]; 17 } 18 i++; 19 } 20 21 for(int j=0;j<7;j++) { 22 if(ans[j]!=0) { 23 cout << money[j] << " " << ans[j] << endl; 24 } 25 } 26 27 }
贪心策略:按面值从大到小选择
证明:
其中一次的选择记为v(i).
若此问题的最优解为S,假设选择v(i)不是最优的,而选择v(j)(j>i),得到最优解S,若用v(i)代替v(j),不会影响后面的选择,仍得到解S,而在假设中,选择v(i)并不是最优的,则产生矛盾,证明贪心策略正确。
三、请说明在本章学习过程中遇到的问题及结对编程的情况
1、本章学习过程中遇到的难题:
贪心算法符合现实生活中解决问题的思路,所以理解起来比较容易。但是对于贪心算法的证明还没有掌握,逻辑性太强有点绕。
2、结对编程的情况:
本章结对编程第一道题目比较简单,和同伴都轻松地解决。但是第二道题目的问题太大了,以为只要定义一个结构体,用一个变量记录原先的相对位置,再将几个数排序,然后删掉最大的数,再按原来的位置输出就好了,最后发现只过了测试点,害,原来是没有理解透题目的意思。
觉得本次结对编程的情况并不理想,效率不高,没有办法共同找到问题所在。继续加油!