uva10073 潜水比赛

【问题描述】  

  在马其顿王国的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.用最快的两个人来回运完最慢的两个(12过河;1返回;最慢两个过河;2返回;12过河)
先按速度排序,每次从第三、四个人开始运,用两种方法中时间短的一种加到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;i<=n;i++)
        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;
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值