1. 程式人生 > >nyoj 47 過河問題(貪心)

nyoj 47 過河問題(貪心)

p.s.emmm…如果寫的不好或者有錯的話一定要記得跟我說啊,千萬不要打我(肥宅大哭.jpg)這題寫的我真的是心塞T^T,我還是個孩子為什麼要這麼對我。
描述
在漆黑的夜裡,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

分析:首先是要分情況,當人數為一,二,三的時候便不多加描述了,因為坑點感覺是在四個人及以上啊。對於四個及以上的情況,有兩種方案:
第一種:讓用時最短的和最長的過去,最短的回來,帶第二長的走,如此迴圈(然後連樣例都過不了,WA的一聲哭出來)
第二種:用時最短的兩個過去,然後回來用時最短的,然後最長的兩個過去,然後第二短的回來,如此迴圈。
都是在剩下不到四個人的時候結束迴圈的。
其中兩種方案需要進行比較,從而選出用時最短的那種方案。(如果不知道為什麼要進行比較可以多寫幾組樣例體會一下)
程式碼如下

#include<stdio.h>
#include<algorithm>
using namespace std;
int a[1010];
int main()
{
    int t, n, i;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i = 0; i < n; i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        int sum = 0;
        while(n >= 4)
        {
            if((a[1] * 2 + a[n-1] + a[0]) > (2 * a[0] + a[n-1] + a[n-2]))
            {  
                sum += a[n-1]; sum += a[0]; sum += a[n-2];sum += a[0]; 
            }
            else
            {
                sum += a[1]; sum += a[0];sum += a[n-1]; sum += a[1]; 
            }
            n -= 2;
        }
        if(n == 3)
            sum += a[1] + a[0] + a[2];
        else if(n == 2)
            sum += a[1];
        else
            sum += a[0];
        printf("%d\n",sum);
    }
    return 0;
}

因為c語言實在有點菜。。。並沒有搞懂qsort。。。所以當時找了個老學姐要來了c++的排序方式,以至於寫的實在一言難盡,下面是補的手寫排序函式(裝死):

void sort(int*arr,int length)
{
    int i=length,j=0;
    int t;
    while(i--)
    {
        j=i;
        while(j--)
        {
            if(arr[i]>arr[j])
            {
                t=arr[i];
                arr[i]=arr[j];
                arr[j]=t;
            }
        }
    }
}

sort(r,length);

為何這部落格寫的我如此心累。。。我實名diss那個學姐T^T,竟讓我們寫部落格。