华师一附中OI组
标题:
手电过河
[打印本页]
作者:
admin
时间:
2018-9-3 17:37
标题:
手电过河
夜晚n位旅行者要过桥,总共只有一个手电筒,一次最多两人过桥,且过桥必须使用手电筒。每位旅行者单独过桥的所需的时间已知,两人结伴渡桥所用的时间为两人中最长的时间。输入人数和每个人过河所需的时间,求解所有人过桥所用的总时间最短是多少。
作者:
admin
时间:
2018-9-3 17:39
分析:因为只有一个手电筒,必定有人过桥之后,还要将手电筒送回来。
若n=1,或n=2 所有人直接过河。
若n=3 ,最快的人往返一次把两个人送过去。
若n=4时,假设四人耗时从少到多依次为a , b, y, z.
那么有两种方案过河,
方案一:ab一起过河,a返回,yz一起过河,b返回接a 耗时b+a+z+b+b
方案二:ay一起过河,a返回,az一起过河,a返回接b 耗时y+a+z+a+b
这两种方案的末状态一定是:最大的两个已经过河,最小的两个留在河这面
两方案的时间差为2b-a-y
当2b>a+y时,采用方案2, 当2b<=a+y时,采用方案1.
若n>4时,该问题相当于两个快的一直在送最慢的两个,因此递归求解,转化成n-2个旅行者的问题。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int p[1100];
int cmp(int a,int b)
{
return a<b;
}
int Time(int n)
{
if(n==1) return p[0];
if(n==2) return p[1];
if(n==3) return p[0]+p[1]+p[2];
if(p[1]*2>=p[0]+p[n-2])
return 2*p[0]+p[n-1]+p[n-2]+Time(n-2);
else
return 2*p[1]+p[0]+p[n-1]+Time(n-2);
}
int main()
{
int T;
int n;
int i,j;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
memset(p,0,sizeof(p));
for(i=0;i<n;i++)
{
scanf("%d",&p[i]);
}
sort(p,p+n,cmp);
printf("%d\n",Time(n));
}
return 0;
}
复制代码
欢迎光临 华师一附中OI组 (http://hsyit.cn/)
Powered by Discuz! X3.2