【问题描述】
在马其顿王国的ohide湖里举行了一场潜水比赛.其中一个项目是从高山上跳下水,再潜水到达终点.这是一个团体项目,一支队伍由n个人组成.在潜水时必须使用氧气瓶,但是每支队伍只有一个氧气瓶.最多两个人同时使用一个氧气瓶,但此时两人必须同步游泳,因此到达终点的时间等于较慢的一个单独游到终点所需要的时间.好在大家都很友好,因此任何两个人都愿意一起游泳.安排一种潜水策略,使得最后一名选手尽早到达终点。
【输入格式】
第1行:一个整数n,表示队伍的人数。
以下n行,每行一个整数,表示第i个人游到终点的时间Ti。
【输出格式】
队伍最早到达终点的时间。
【样例输入1】
3
1
3
4
【样例输入2】
6
1
2
5
6
8
9
【样例输出1】
8
【样例输出2】
27
【数据范围】
n<=1000, 0<Ti<=100000
很清楚地是:
如果只有1人,则ans=a[1]
如果只有2人,则ans=max(a[1],a[2])
如果只有3人,则ans=a[1]+a[2]+a[3]
不难想到有两种方法
1.用速度最快的人来回一个一个地运人
2.用最快的两个人来回运完最慢的两个(1、2过河;1返回;最慢两个过河;2返回;1、2过河)
先按速度排序,每次从第三、四个人开始运,用两种方法中时间短的一种加到ans中(注意中途需要加上一个已过河的a[1]或a[2]返回用的时间,因为下一次需要他们在起点)。直到只有4个人或3个人,此时就很好计算了。
#include<cstdio>
#include<algorithm>
#define maxn 1005
using namespace std
int n,ans=0,a[maxn]
int read()
{
int x=0,ok=0
char ch
ch=getchar()
while((ch<'0'||ch>'9')&&ch!='-') ch=getchar()
while((ch>='0'&&ch<='9')||ch=='-')
{
if(ch=='-') ok=1
else x=x*10+ch-'0'
ch=getchar()
}
return ok==1?-x:x
}
void in()
{
n=read()
for(int i=1
a[i]=read()
sort(a+1,a+n+1)
}
void task()
{
int t=n-1
while(1)
{
if(n==1)
{
ans+=a[1]
break
}
if(n==2)
{
ans+=a[1]+a[2]
break
}
if(n==3)
{
ans+=a[1]+a[2]+a[3]
break
}
if(n==4)
{
ans+=min(a[t]+a[1]+a[t+1]+a[2]+a[1],a[2]+a[1]+a[t+1]+a[2]+a[2])
break
}
ans+=min(a[t]+a[1]+a[t+1]+a[1],a[2]+a[1]+a[t+1]+a[2])
t-=2
n-=2
}
printf("%d",ans)
}
int main()
{
freopen("in.txt","r",stdin)
in()
task()
return 0
}