Crossing River
Time Limit: 1000MS Memory Limit: 10000K
Description
A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the boat back and forth so that all people may cross. Each person has a different rowing speed; the speed of a couple is determined by the speed of the slower one. Your job is to determine a strategy that minimizes the time for these people to get across.
Input
The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. The first line of each case contains N, and the second line contains N integers giving the time for each people to cross the river. Each case is preceded by a blank line. There won't be more than 1000 people and nobody takes more than 100 seconds to cross.
Output
For each test case, print a line containing the total number of seconds required for all the N people to cross the river.
Sample Input
1
4
1 2 5 10
Sample Output
17
Source
题解:
根据题意可以判断这道题用贪心。
做题时需要注意两点:
1.两人一起时速度由较慢的人速度决定。
2.船最多可承载两个人,划过去后必须有人划回来。
1 | 2 | 5 | 10 | 时间 | 合计 |
0 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 0 | 0 | 2 | 2 |
0 | 1 | 0 | 0 | 1 | 3 |
0 | 1 | 1 | 1 | 10 | 13 |
0 | 0 | 1 | 1 | 2 | 15 |
1 | 1 | 1 | 1 | 2 | 17 |
1 | 2 | 5 | 10 | 15 | 时间 | 合计 |
0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 0 | 0 | 0 | 2 | 2 |
0 | 1 | 0 | 0 | 0 | 1 | 3 |
0 | 1 | 0 | 1 | 1 | 15 | 18 |
0 | 0 | 0 | 1 | 1 | 2 | 20 |
1 | 0 | 1 | 1 | 1 | 5 | 25 |
0 | 0 | 1 | 1 | 1 | 1 | 26 |
1 | 1 | 1 | 1 | 1 | 2 | 28 |
如果不用有人划回来,为了时间最短,最好时间相近的人两两组队,以1、2、5、10为例,可以1和2组队,5和10组队,这样时间可以每组中用时多的一个即可,其他任何组合方式都无法比这种用的时间短。如果人数为奇数个,则让前三个为组合。因此先将用时排序,由于数据量较小,任何排序方法都可以。
题目中要求船划过去后必须有人划回来,时间最短有两种可能(第一组除外,设该组中快的为A,慢的为B,所有人中最快的为C,第二快的为D):
可能1:
C和A过去,C回来。
C和B过去,C回来。
用时为2*t(C)+t(A)+t(B).
可能2:
C和D过去,C回来。
A和B过去,D回来。
用时为2*t(D)+t(C)+t(B).
如果t(C)+t(A)<2*t(D),则可能1时间短,否则可能2时间短。
将每一组最短时间加起来,最后不要忘记第一组的时间。
当组数为偶数时,最后最快的和第二快的一起过去,加上第二快的时间。
当组数为奇数时,第一组用可能1,但最后最快的不用回来,即加上第一快、第二快和第三快的时间。
<span style="font-size:18px;">#include<cstdio>
#include<cmath>
int a,b,c,d,e,f,g,i,m,n,j,x[10000]={0};
int main()
{
scanf("%d",&a);
for(n=1;n<=a;n++)
{
scanf(" %d",&b);
for(i=1;i<=b;i++)
{
scanf(" %d",&x[i]);
for(m=1;m<i;m++)
{
if(x[i]<x[m])
{
c=x[i];
x[i]=x[m];
x[m]=c;
}
}
}
if(b%2==0)
{
c=x[2];
for(i=4;i<=b;i=i+2)
{
if(x[i]+x[1]+x[2]*2<x[i-1]+x[i]+x[1]*2) c=c+x[i]+x[1]+x[2]*2;
else c=c+x[i-1]+x[i]+x[1]*2;
}
}
else
{
c=c+x[1]+x[2]+x[3];
for(i=5;i<=b;i=i+2)
{
if(x[i]+x[1]+x[2]*2<x[i-1]+x[i]+x[1]*2) c=c+x[i]+x[1]+x[2]*2;
else c=c+x[i-1]+x[i]+x[1]*2;
}
}
printf("%d\n",c);
}
return 0;
}</span>