题目大意:
一群人晚上遇到一条河,只有一个手电筒和一只能容纳两个人的船,每个人的过河时间不同,当两个人同坐一条船的时候按时间长的计算,问怎么样才能够使得所有人均过河的时间最短。
题目分析:
设有n个人,且第i个人过河所需要的时间是a[i],所需要的总的过河时间是sum;
a[n]按升序排列后;
当n=1时,sum=a[1];
当n=2时,sum=a[2];
当n=3时,sum=a[2]+a[1]+a[3];
当n等于4时,这个时候就会出现两种情况:
(1)过河随度最快的分别和剩下的三个过河,即sum=a[2]+a[1]+a[3]+a[1]+a[4]
(2)过河时间最快的和次快的先过河,然后最快的送手电筒回来之后最慢的和次慢的过河之后次快的再送手电筒回来和最快的过河。那么sum=a[2]+a[1]+a[4]+a[2]+a[2];
对比1、2,如果我们不考虑a[1],a[2],也就是说考虑先将a[3],a[4]过河,那么sum1=a[4]+a[1]+a[3]+a[1]
sum2=a[2]+a[1]+a[4]+a[2],我们只要比较出这两种情况的更优解即可。
sum=Min(sum1+sum2)+a[2];
当n>4时,均可以转换成上面的三种情况啊。
代码:
#include<stdio.h>
#include<algorithm>
#define N 1002
int Min(int a,int b){
return a<b?a:b;
}
int main()
{
int t,n;
int a[N];
int i,j;
int m1,m2;
int sum;
scanf("%d",&t);
while(t--){
sum=0;
a[0]=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
std::sort(a+1,a+n+1);
while(n>=4){
m1=a[1]+2*a[2]+a[n];
m2=a[1]*2+a[n]+a[n-1];
sum+=Min(m1,m2);
n-=2;
}
if(n==1)
sum+=a[1];
else
if(n==2)
sum+=a[2];
else
if(n==3)
sum+=a[1]+a[2]+a[3];
printf("%d\n",sum);
}
return 0;
}
非常经典的一道贪心题!