电池的寿命
总时间限制: 1000ms 内存限制: 65536kB
描述
小S新买了一个掌上游戏机,这个游戏机由两节5号电池供电。为了保证能够长时间玩游戏,他买了很多5号电池,这些电池的生产商不同,质量也有差异,因而使用寿命也有所不同,有的能使用5个小时,有的可能就只能使用3个小时。显然如果他只有两个电池一个能用5小时一个能用3小时,那么他只能玩3个小时的游戏,有一个电池剩下的电量无法使用,但是如果他有更多的电池,就可以更加充分地利用它们,比如他有三个电池分别能用3、3、5小时,他可以先使用两节能用3个小时的电池,使用半个小时后再把其中一个换成能使用5个小时的电池,两个半小时后再把剩下的一节电池换成刚才换下的电池(那个电池还能用2.5个小时),这样总共就可以使用5.5个小时,没有一点浪费。
现在已知电池的数量和电池能够使用的时间,请你找一种方案使得使用时间尽可能的长。
输入
输入包含多组数据。每组数据包括两行,第一行是一个整数N (2 ≤ N ≤ 1000),表示电池的数目,接下来一行是N个正整数表示电池能使用的时间。
输出
对每组数据输出一行,表示电池能使用的时间,保留到小数点后1位。
样例输入
2
3 5
3
3 3 5
样例输出
3.0
5.5
对于贪心问题,从解题的过程来看我们应该是更应该关注结果,而不应该关注过程或者方法。对于这道题而言,我们就不能关心他到底是在什么时候换电池的,而应该只关心电池到底能用多久。
一般来讲,贪心都要关心至少两种情况,这道题也如此。
如果一个电池的寿命大于其他所有电池寿命之和,很明显,电池的寿命就是其他所有电池寿命之和。但如果最大电池寿命小于其他所有电池寿命之和呢?仔细思考一下,我们始终使用剩余寿命最长的两个电池,相当于是让电池剩余寿命更短,剩余寿命越短意味着利用率越高。在最大电池寿命小于其他所有电池寿命之和的时候,根据这样的算法,所有电池都能够用完,电池的总寿命=寿命之和/2。
反观一来我们想到的简单情况,事实上也是一种特殊情况,在一直使用剩余寿命最长的电池的条件下始终都用了使用寿命最长的那个电池,思路来讲是一样的,只是因为结果不同,写出来的代码也就不同。
参考代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a;
int battery[1005];
while(~scanf("%d",&a)&&a)
{
int sum=0;
memset(battery,0,sizeof(battery));
for(int i=0; i<a; i++)
{
scanf("%d",&battery[i]);
sum+=battery[i];
}
sort(battery,battery+a);
if(sum-battery[a-1]>battery[a-1])
{
printf("%.1f\n",(double)sum/2);
}
else
{
printf("%.1f\n",(double)sum-battery[a-1]);
}
}
return 0;
}