Description
Input
Output
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>