poj1700题解

//Memory 144K Time 16MS
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    scanf("%d", &n);

    while (n--) {
        int peopleNum;
        scanf("%d", &peopleNum);
        int arr[1010];
        for (int i = 0; i < peopleNum; i++)
            scanf("%d", &arr[i]);

        sort(arr, arr + peopleNum);
        int useTime = 0;
        //每次运送两个人
        //当过河的总人数小于或等于3个人时,可直接推导出最优方案
        //即每次都让时间最少的返回,然后带时间最长的一起过河
        while (peopleNum) {
            if (peopleNum == 1) {
                useTime += arr[0];
                break;
            } else if (peopleNum == 2) {
                useTime += arr[1];
                break;
            } else if (peopleNum == 3) {
                useTime += arr[2] + arr[0] + arr[1];
                break;
            } else {
                //两种方案
                //1.先让时间最少的和时间最长一起过河,然后时间最少的返回
                //在让时间最少的带时间次最长的一起过河,然后时间最少的返回
                //2.先让时间最少和时间次最少一起过河,然后时间最少的返回
                //时间最少的下船,让时间最多的和时间次最多的一起过河,然后时间次最少的返回

                //若在当前未过河的人数中,方案1的时间比方案2的时间长,使用方案2,反之使用方案1
                if (arr[peopleNum - 2] + 2 * arr[0] + arr[peopleNum - 1] > 2 * arr[1] + arr[0] + arr[peopleNum - 1])
                    useTime += 2 * arr[1] + arr[0] + arr[peopleNum - 1];
                else
                    useTime += arr[peopleNum - 2] + 2 * arr[0] + arr[peopleNum - 1];
            }
            peopleNum -= 2;
        }
        printf("%d\n", useTime);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值