贪心基础/C-Crossing River

来源:互联网 发布:淘宝评分 编辑:程序博客网 时间:2024/05/19 03:26

C-Crossing River

A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the boat back and forth so that all people may cross. Each person has a different rowing speed; the speed of a couple is determined by the speed of the slower one. Your job is to determine a strategy that minimizes the time for these people to get across.

Input

The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. The first line of each case contains N, and the second line contains N integers giving the time for each people to cross the river. Each case is preceded by a blank line. There won't be more than 1000 people and nobody takes more than 100 seconds to cross.

Output

For each test case, print a line containing the total number of seconds required for all the N people to cross the river.

Sample Input

1
4
1 2 5 10

Sample Output

17




题意:

有T组数据,每组N个人过河,只有一条船,船上最多载两个人,当有两个人坐船过河时,过河时间为耗时更长的人的时间,求每组人过河的最短时间


思路:

这道题最重要的地方在于找出四个人过河时,用时最少的时间方法。

假设速度最快的四个人为fast1,fast2,fast3,fast4,根据题目给的样例,我刚开始认为用时最少的方法是:fast1和fast2过河,fast1回来,fast3和fast4过河,fast2回来,这时候1,2在原来那岸,3和4已经过河,然后更新fast3和fast4的速度,就是速度最快的两个人不断和另外两个人搭配,如果人数小于4个人,就直接计算

但是,算了几组数据之后我发现有些时候fast1和fast3过河,fast1回来,然后fast1和fast4过河,fast1回来用的时间更短。所以我觉得我还没有找到用时最少的方法的具体根据。

在又算了几组数据之后,我发现四个人时用时最短的方法总在上述两个方法中交替,为了确定,我百度了题目,看了一下网上这道题的做题思路,发现的确是这样,我就开始敲代码。

然而不幸的是,交上去发现WA了,然后我反复验证了好几遍代码,觉得自己并没有写错,于是我看了网上的题解,发现正确的做法应该是倒序排列时间,然后再两个两个和用时最快的两个人搭配,而我是正序的。

我本来是用倒序优先队列存的时间,但是因为我觉得队列不能访问第二快的时间,也就是倒数第二个元素(如果实际上是可以的,希望可以告知),所以就改成了数组。

所以这题的总思路是:将时间从大到小排列,fast1和fast2是最短的两个时间,fast3和fast4是目前还没过河的最大的两个时间,判断上述两种方法的用时长短,将更短的加到总时间sum中,然后更新fast3和fast4,重复步骤,当人数小于四,就直接计算。


AC代码:

#include<iostream>
#include <algorithm>
#include <cstdio>
#include <queue>

using namespacestd;

bool cmp(int a,int b){
    return a>b;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int N,sum=0,time[1005],fast1,fast2,fast3,fast4;
        scanf("%d",&N);
        for(int i=0;i<N;i++)
            scanf("%d",&time[i]);
        sort(time,time+N,cmp);
        if(N<=2){
            printf("%d\n",time[0]);
            continue;
        }
        else if(N==3){
            printf("%d\n",time[0]+time[1]+time[2]);
            continue;
        }
        else{
            fast1=time[N-1];
            fast2=time[N-2];
            for(int i=0;i<N-2;i+=2)
            {
                int sum1=0,sum2=0;
                if(i+1==N-2){
                    sum+=time[i]+fast1+fast2;
                    continue;
                }
                fast3=time[i+1];
                fast4=time[i];
                if(i+2==N-2){
                    sum1+=fast1+fast2+fast2+fast4+fast2;
                    sum2+=fast1+fast1+fast3+fast4+fast2;
                    sum+=min(sum1,sum2);
                }
                else{
                    sum1+=fast1+fast2+fast2+fast4;
                    sum2+=fast1+fast1+fast3+fast4;
                    sum+=min(sum1,sum2);
                }
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}