过河问题
时间限制:1000 ms | 内存限制:65535 KB
难度:5
描述
在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,N个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,N人所需要的时间已知;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题是,如何设计一个方案,让这N人尽快过桥。
输入
第一行是一个整数T(1<=T<=20)表示测试数据的组数
每组测试数据的第一行是一个整数N(1<=N<=1000)表示共有N个人要过河
每组测试数据的第二行是N个整数Si,表示此人过河所需要花时间。(0<Si<=100)
输出
输出所有人都过河需要用的最少时间
样例输入
1
4
1 2 5 10
样例输出
17
来源
解题思路:
两种方法:
方法一: 由用时最短的那个人啊a[0],依次和另一个人过河,然后返回。每次的时间是 2*a]+a[i]+a[i-1]。(时间节省在返回的人身上)。
方法二:
由前两个先过去,然后1返回,a[i]和[i-1]过去。a[1]返回。重复。每次过河的时间是a[0]+a[i]+2*a[1](时间节省在过河的人身上,相应返回时间增加了).
比较两次的时间最短的就是过河最短的时间。
程序代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int a[1100],time0,n,time1,time2;
int cmp(const void *a,const void *b)
{
return *(int *)a - *(int *)b;
}
int min(int a,int b)
{
if(a>b)
return b;
else
return a;
}
void f()
{
int i;
if(n&1)
{
for(i=4;i<n;i+=2)
{
time1=2*a[0]+a[i]+a[i-1]; //分两种情况计算
time2=a[0]+a[i]+2*a[1];
time0+=min(time1,time2);
}
time0+=a[0]+a[2];
}
else
{
for(i=3;i<n;i+=2)
{
time1=2*a[0]+a[i]+a[i-1];
time2=a[0]+a[i]+2*a[1];
time0+=min(time1,time2);
}
}
}
int main()
{
int T,i,sum;
scanf("%d",&T);
while(T--)
{
memset(a,0,sizeof(a));
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
qsort(a,n,sizeof(a[0]),cmp); // 按时间大小由小到大排序
sum=0;
time0=a[1];
if(n==3)
{
time0+=a[0]+a[2];
}
else
f();
printf("%d ",time0);
}
return 0;
}