【Description】
一群人划船过河,河边只有一条船,这条船可以容纳两个人,船过河后需要一人将船开回,以便所有人都可以过河,每个人过河速度不一样,两个人过河速度取决于慢的那个人,请问最少需要多久让所有人过河?
【Input】
第一行输入人数n;
第二行输入每个人过河所需的时间;
【Output】
输出需要的最少时间
【Sample Input】
4
1 2 5 10
【Sample Output】
17
题目分析:
两种方法,较容易想到的是第一种方式:
第一种办法:先让1 2过去(2分钟),1回来(1分钟),1 5过去(5分钟),1回来(1分钟),1 10再过去(10分钟),总共需要19分钟就可以让四个人都过去。
而正确答案是第二种办法:先让1 2过去(2分钟),1回来(1分钟),5 10过去(10分钟),2回来(2分钟),1 2再过去(2分钟),总共需要17分钟就可以让四个人都过去。
本题的关键在于把最慢的和次慢的两个人运过河,因此只要大于四个人的情况下:只需要将这两种方式这两个人运过河的时间做对比:
第一种:T4+T1+T3+T1
第二种:T2+T1+T4+T2
对比之后取短的就行
源码如下:
#include<iostream>
#include<algorithm>
using namespace std;
/*void swap(int a[],int x,int y)
{
int temp=a[x];
a[x]=a[y];
a[y]=temp;
}
int Getpoint(int a[],int low,int high)
{
int point=a[low];
while(low<high)
{
while(low<high && a[high]>=point)
high--;
swap(a,low,high);
while(low<high && a[low]<=point)
low++;
swap(a,low,high);
}
return low;
}
void Quick(int a[],int low,int high)
{
if(low<high)
{
int point=Getpoint(a,low,high);
Quick(a,low,point-1);
Quick(a,point+1,high);
}
}*/
int Cross(int a[],int n)
{
sort(a,a+n);//这里运用了内部的排序 想提升时间可以运用快排 上面的代码是快排
int time=0;
while(n>3)//负责减最慢和次慢的人运过河
{
if( (2*a[0]+a[n-2]+a[n-1])<=(2*a[1]+a[0]+a[n-1]) )
time=time+2*a[0]+a[n-2]+a[n-1];
else
time=time+2*a[1]+a[0]+a[n-1];
n=n-2;//运过去两个人
}
if(n==3)
time=time+a[0]+a[1]+a[n-1];
if(n==2)
time=time+a[n-1];
if(n==1)
time=time+a[0];
return time;
}
int main()
{
int n;//输入一共多少个人过河
cin>>n;
int a[255];
memset(a,0,sizeof(a));//初始化
for(int i=0;i<n;i++)
cin>>a[i];//输入每个人过河的时间
cout<<Cross(a,n)<<endl;
return 1;
}