算法第四章作业
1.对贪心算法的理解
贪心算法每次选择目前最优的解,通过一系列局部最优来获得整体最优。贪心算法只有在具有贪心选择性质时才能保证获得整体最优。贪心算法的基本要素是:贪心选择性质和最优子结构性质。贪心算法通常以自顶向下的方式进行,每次贪心选择就将原问题转化为规模更小的子问题。贪心算法所作的选择可以依赖于以往所做过的选择,但绝不依赖于将来的选择,也不依赖于子问题的解,因此贪心算法与其他算法相比具有一定的速度优势。
2.请选择一道作业题目说明你的算法满足贪心选择性质
有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小。
输入格式:
共两行,第一行为n(1≤n≤1000);第二行分别表示第1个人到第n个人每人的接水时间T1,T2,…,Tn,每个数据之间有1个空格。
输出格式:
输出为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。
输入样例:
10
56 12 1 99 1000 234 33 55 99 812
输出样例:
291.90
代码:
#include<iostream> #include<algorithm> #include<iomanip> #define MAX 1000 using namespace std; struct queue{ int value; int p; }; queue a[MAX]; bool cmp(const queue &a, const queue&b) { if(a.value == b.value)//时间相同,先来的先排队 return a.p < b.p; else return a.value < b.value; } int main() { int n; cin>>n; for(int i=0;i<n;i++) { cin>>a[i].value; a[i].p=i; } sort(a,a+n,cmp); double sum=0; for(int i=0;i<n;i++) { sum+=(n-i-1)*a[i].value; } cout<<fixed<<setprecision(2)<<sum/n<<endl; return 0; }
要使n个人的平均等待时间最小,即接水时间短的优先,首先将接水时间从小到大进行排序,再进行总等待时间的计算(sum+=(n-i-1)*a[i].value)。每次选择目前最优的解(最短时间),通过一系列局部最优来获得整体最优。
3.请说明在本章学习过程中遇到的问题及结对编程的情况
这一章运用贪心算法最主要的就是找出最优方案有时候就会因为方案并非最优而出现问题。结对编程中PTA上的删数问题这道题,一开始我们提出的几个方案都被反例给否定,后来总算找到了,但是在控制变量循环的部份犯了难,后来以为自己搞懂了,结果老师一问删数的顺序,才发现我得出的是错误的顺序QAQ。幸亏后来和同伴两个人讨论之下终于搞懂了,感受到结对编程的好处就是可以交换对方的看法和见解了。