過河問題

貪心算法

過河問題

時間限制:1000 ms | 內存限制:65535 KB
難度:5
描述
在漆黑的夜裏,N位旅行者來到了一座狹窄而且沒有護欄的橋邊。如果不借助手電筒的話,大家是無論如何也不敢過橋去的。不幸的是,N個人一共只帶了一隻手電筒,而橋窄得只夠讓兩個人同時過。如果各自單獨過橋的話,N人所需要的時間已知;而如果兩人同時過橋,所需要的時間就是走得比較慢的那個人單獨行動時所需的時間。問題是,如何設計一個方案,讓這N人儘快過橋。

輸入
第一行是一個整數T(1<=T<=20)表示測試數據的組數
每組測試數據的第一行是一個整數N(1<=N<=1000)表示共有N個人要過河
每組測試數據的第二行是N個整數Si,表示此人過河所需要花時間。

(0<Si<=100)

輸出
輸出所有人都過河需要用的最少時間
樣例輸入
1
4
1 2 5 10
樣例輸出
17


#include <stdio.h>

void qsort(int num[], int l, int r)
{
    if (l < r)
    {
        int i = l, j = r, x = num[l];
        while (i < j)
        {
            while (i < j && num[j] >= x)
                j--;
            if (i < j)
                num[i++] = num[j];
            while (i < j && num[i] < x)
                i++;
            if (i < j)
                num [j--] = num[i];
        }
        num[i] = x;
        qsort(num, l, i-1);
        qsort(num , i+1, r);
    }
}

int main ()
{
    int i, j, t, n, num[1000];
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d",&n);

        for (i = 0; i < n; i++)
            scanf("%d", &num[i]);

        qsort(num, 0, n-1);  // 快排

        int sum = 0;
        while (n >= 4)
        {
            if (num[1] + num[0] + num[n-1] + num[1] < num[n-1] +num[0]+num[0]+num[n-2] )
            {
                // 兩個人同時接
                sum += num[1]; // 最快的和第二快的過河
                sum += num[0]; // 最快的回來送燈(剩下第二快的)
                sum += num[n-1]; // 最慢的和第二慢的過河
                sum += num[1];   // 第二塊的回去送燈
                // 還有第二快的 和最快的沒回來
            }
            else
            {
                // 一個人接
                sum += num[n-1];   // 最快的和最慢的過河
                sum += num[0];    //  最快的回去送燈
                sum += num[n-2];   // 最快的把 第二慢的接過去
                sum += num[0];  //  最快的回去  
                //還有第二快的和最快的沒回來
            }
            n -= 2;   // 因爲過去了兩個人 還有兩個人
        }
        if (n == 3)
        {
            sum +=  num[2] + num[0] + num[1];
        }
        if (n == 2)
        {
            sum += num[1];
        }
        if (n == 1)
        {
            sum += num[0];
        }

        printf("%d\n", sum);

    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章