POJ 1700 Crossing River (贪心)

http://poj.org/problem?id=1700
题目大意:有n个人要过一条河,每个人过河都需要一个时间,有一艘船,每次过河只能最多装两个人。两个人划船过河所需的时间都取决于过河时间长的那个人,安排一个过河方案,让所有人用最短的时间全部过河。
贪心中经典的过河问题,说实话不看学长的PPT真不会。。。
首先显然要排个序。
n==1和n==2的情况很显然一次过去就完了;
n==3的情况也很显然,a[1]和a[3]过去,a[1]回来,a[1]和a[2]在过去,总共要花a[1]+a[2]+a[3];
然后考虑n==4的情况,假设四人1-4分别是a,b,c,d,这里就有两种可选方案:
1. 过河顺序为:ac、a、ad、a 时间消耗:t1=2a+c+d
2. 过河顺序为:ab、a(b)、cd、b(a) 时间消耗:t2=a+2b+d
因为t1−t2=a+c−2b,所以选择两种方案的哪一种,和a+c−2b的值有关;
这样不管n等于几,每次可以选第1,2个和第n,n-1个通过以上比较选择更优的方案将第n和n-1个人送过河,直到送到只剩2或3人,参见前面的情况。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdlib>
using namespace std;
int a[1010],T,n;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
        sort(a+1,a+1+n);
        if(n==1||n==2)
        {
            printf("%d\n",a[n]);
            continue;
        }
        if(n==3)
        {
            printf("%d\n",a[n]+a[n-1]+a[1]);
            continue;
        }
        int p=a[1],q=a[2],r=n-1,s=n,ans=0;
        while(1)
        {
            if(r==1&&s==2)
            {
                ans+=a[2];
                break;
            }
            if(r==2)
            {
                ans+=a[3]+a[2]+a[1];
                break;
            }
            if(p-2*q+a[r]<0)
            {
                ans+=2*p+a[s]+a[r];
                s-=2;
                r-=2;
            }
            else
            {
                ans+=p+2*q+a[s];
                s-=2;
                r-=2;
            }
        } 
        printf("%d\n",ans);
    } 
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值