算法第四章作业
1,对贪心算法的理解
(1)贪心算法是通过一系列的选择来得到问题的解,所做的每个选择都是当前状态下局部最好的选择,即贪心选择。
(2)贪心算法有两个重要的性质:贪心选择性质和最优子结构性质
其中贪心选择性质,所求问题的整体最优解可以通过一系列局部最优的选择来得到
就是说当前问题可以通过选择最好的那个元素(比如货币找零问题,总能够通过选择当前小于总的找零数的最大面额的钞票来得到最优解)来解决问题
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,换句话说,当考虑做何种选择的时候,我们只考虑对当前问题最佳的选择而不考虑子问题的结果。这是贪心算法可行的第一个基本要素。
贪心算法以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。
对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。
2,请选择一道作业题目说明你的算法满足贪心选择性质
例题:
4-1 程序存储问题 (90分)
设有n 个程序{1,2,…, n }要存放在长度为L的磁带上。程序i存放在磁带上的长度是 li,1≤i≤n。 程序存储问题要求确定这n 个程序在磁带上的一个存储方案, 使得能够在磁带上存储尽可能多的程序。 对于给定的n个程序存放在磁带上的长度,计算磁带上最多可以存储的程序数。
输入格式:
第一行是2 个正整数,分别表示文件个数n和磁带的长度L。接下来的1行中,有n个正整数,表示程序存放在磁带上的长度。
输出格式:
输出最多可以存储的程序数。
输入样例:
在这里给出一组输入。例如:
6 50
2 3 13 8 80 20
输出样例:
在这里给出相应的输出。例如:
5
代码:
#include<iostream> #include<algorithm> using namespace std; int a[1000],n,L; int main(){ cin>>n>>L; for(int i=0;i<n;i++){ cin>>a[i]; } sort(a,a+n); int sum=0,count=0; for(int i=0;i<n;i++){ sum+=a[i]; if(sum>L){ break; } count+=1; } cout<<count; }
算法思想是:先将程序放在磁带上的长度按从小到大排序,如果最短的程序都比磁带长度长,则输出零;循环中每次挑选数组中剩下的最短的程序,直到放不下为止。
贪心选择就是每次挑选最短的程序,这样才能保证存入的程序数量最多。
证明我的贪心选择(反证法)
磁带长度为50 ,6个程序长度分别为
2 10 13 8 80 27
假如不是每次都选最短的
假如选了 10 13 27 能放三个程序
实际上,选择用 2 和 8 代替上面的13,就能放下 2 8 10 13 四个程序,比原来的选择更优,说明我的假设是错的,即每次选择最小的选择是正确
的。
3,请说明在本章学习过程中遇到的问题及结对编程的情况
(1)遇到的问题:有时候不知道如何做贪心选择,不知道什么样的选择才合适。
(2)结对编程情况:上机课一起求解4-2 删数问题时,原因是贪心策略选错了,导致有一部分测试点过不了。课上有一起讨论,互相帮助,第三题4-3 最优合并问题 是搭档教我思路,按着思路我自己把代码打出来了。