1. 程式人生 > >C語言貪心演算法之過河問題

C語言貪心演算法之過河問題

過河問題

時間限制: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>
#include<algorithm>
using namespace std;
int min(int a,int b)
{
    if(a<b)
        return a;
    else
        return b;
}
int a[1001];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int i,n,time=0;
        scanf("%d",&n);
        for(i=0; i<n; i++)
        {
            scanf("%d",&a[i]);
        }
        sort(a,a+n);
        while(n>3)
        {
            time+= min(2*a[1]+a[0]+a[n-1],a[n-2]+a[0]*2+a[n-1]);//2*a[1]+a[0]+a[n-1]用時最短和用時第二短的人一起過去,然後用時最短的人把手電筒帶回來,然後用時最長和用時第二長的人一起過去,用時第二短的人回來。a[n-1]+2*a[0]+a[n-2]表示:用時最長的人和用時最短的人先一起過去,然後用時最短的人把手電筒帶回來,再和用時第二長的人一起過去,用時最短的人回來。
            n -= 2;//減去過去的倆人
        }
        if(n==1)
            time+=a[0];
        if(n==2)
            time+=a[1];
        if(n==3)
            time+=a[0]+a[1]+a[2];//a[1]為倆人過河所用時間,加上a[0]回來時間
        printf("%d\n",time);
    }
    return 0;
}
或:
一個人的時候沒話說
兩個人是時間較長的那個人
三個人的時候,先讓第一短時間的人帶時間最長的過去,時間短的再返回,帶第二短的人過去
四個人及其以上的時候,有兩種方法時間較短
      1.第一短的帶最長的,再回來帶第二短的,依次帶完
      2.第一短帶第二短,第一短回來,把手電給最長和第二長,再讓第二短回來
      這兩種方法只是送過去兩個人