“钞票数量”问题的解决方法,用到的就是贪心算法。
贪心算法, 是一种在每一步选择中都采取当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。也就是说,不是从整体最优上加以考虑,他所作出的仅是在某种意义上的局部最优解。
因此还需要保证:当前子问题的最优解一定可以推出全局最优解。
就如:每种纸币的面额都是比自己面值小的钞票的两倍或以上。
当使用一张较大面额时,若用较小面额钞票替换,则需要
两张或更多的钞票。
如果新增7元面值的钞票,当需要支付14元时,当前选择10元面值的钞票无法保证
最后得到的结果一定是最优的。
选7+7要好干10+1+1+1+1
有一个4*4的网格,网格中的数字代表走到这个格子需要消耗的时间,
左上角有一个棋子,棋子每次只能往下走或者往右走,现在要让棋子
走到右下角,请问怎么走所耗费的时间最短?
因为贪心只能得到局部的最优解。
这个问题中的局部最优并不是全局最优,所以每次用贪心前要先考虑下使用贪心能不能达到全局最优解!
贪心算法没有固定的算法框架,算法设计的关键是贪心策
略的选择。
题目要求平均等待时间最小,意思就是n个人的总等待时间最小。
假设有10个人要接水,他们接水的时间分别为:
56、12、1、99、1000、234、33、55、99、812
如果按照上面的顺序接水,第一个接水的人需要花费56分钟,那除他之外的所有人都要花费56分钟,总共等待时间就是56*9=504分钟。
然后第二个接水的人需要花费12分钟,那除了第一个接水的人及他之外所有人都要花费12分钟,总共等待时间就是12*8=96分钟。
#include <cstdio>
#include <algorithm>
using namespace std;
int n, a[1005];
double sum;
int main(){
scanf("%a", &n);
for(int i=1; i <= n; i++)scanf("%d", &a[i]);
sort(a+1, a+n+1);
for(int i=1; i<n; i++){
sum+=(n-i)*a[i];
}
sum=sum/n;
printf("%.21f", sum);
return 0;
}