过河问题 题解

 题目描述

几个人过河,每次过两人一人回,速度由慢者决定,问过河所需最短时间。

输入格式

输入 t 组数据,每组数据第 1 行输入 n;

第 2 行输入 n 个数,表示每个人过河的时间。

输出格式

输出 t 行数据,每行 1 个数,表示每组过河最少时间。

输入输出样例

输入数据 1

1

4

1  2  5  10

输出数据 1

17

思路:

用贪心

我们把运两个人到对岸的时间作为比较当前(因为是贪心,所以只比较当前最优,不知道的读者可以去查一下贪心)最优方法的标准,通过题目分析可知,运两个人有两种可能最优的方法,一是用最快的运最慢的,其次是次慢的;为什么不从次快开始运呢,这其实只是作者的小习惯,不过从次快开始也是可以的。如果从次快开始应该把sort()改成从大到小就行了,但可能还要改一些地方,这里只是稍稍说说。第二种方法是先把最快与次快的先送过去,再让最快把船送回,然后最快下船,再把最慢与次慢也送过去(之所以这样是因为次慢与最慢一起走只用花最慢渡河的时间就行了,用最快一个一个送太久),然后次快送回船。其实最快与次快的作用就是送船。最慢与次慢送船的话太久了。然后我们统计两种方法的时间,把sum加上两种方法的时间的最小值就可以了。这道题的难点其实就是贪心策略,是s+两种方法的时间的最小值,代码很简单。还有一点重复,上述所说的方法只是指运两个人到对岸的方法。

代码:

#include<bits/stdc++.h>

using namespace std;

long long a[200000010];

int main(){

    long long t;

    cin>>t;

    for(long long i=1;i<=t;i++){

        long long n;

        cin>>n;

        for(long long j=1;j<=n;j++){

            cin>>a[j];

        }

        if(n>1){//这里要特判,不然n==1什么都不输出

            sort(a+1,a+n+1);

            long long s=0;

            while(n>3){

                s+=min(a[2]+a[1]+a[n]+a[2],a[n]+a[1]+a[n-1]+a[1]);

                n-=2;

            }

            if(n==3){

                s+=a[2]+a[1]+a[3];

            }else{

                s+=a[2];

            }

            cout<<s<<endl;

        }else{

            cout<<a[1]<<endl;

        }

    }

    return 0;

}

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值