ACM 過河問題

OpenSoucre發表於2014-04-01

過河問題

時間限制: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

此題是阿里的一道筆試題,主要用貪心演算法求解
分成兩種情況(假設時間已經排序)

(1)最小時間把次最大和最大的時間送過去,花費的時間為2s[0]+s[n-2]+s[n-1]
  如 1 7 8 9,則為1把9送過去,1回來,1再把8送過去,1在回來,則能把8,9送過去,時間為19
  像 1 2 4 5,則為1把5送過去,1回來,1再把4送過去,1在回來,則能把4,5送過去,時間為11
(2)最小和次小把最大和次大一起送過去,話費時間為s[0]+2s[1]+s[n-1]
如 1 7 8 9,則為1,7送過去,1回來,8,9送過去,7回來,則能把8,9送過去,時間為24
像 1 2 4 5,則為1,2送過去,1回來,4,5送過去,2回來,則能把4,5送過去,時間為10
故兩種方法中選取最優的
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main(){
    int T;
    cin >> T;
    for(int icase = 0; icase < T; icase++){
        int n;
        cin >> n;
        vector<int> s(n);
        for(int i = 0 ;i < n; ++i) cin >> s[i];
        sort(s.begin(),s.end());
        vector<int> ss;
        int res = 0;
        if(n > 3){
            while(n>3){
                res+=min(2*s[0]+s[n-2]+s[n-1],s[0]+2*s[1]+s[n-1]);
                n-=2;
            }
        }
        if(n <= 2){
            res+=s[n-1];
        }else if(n == 3){
            res+=s[0]+s[1]+s[2];
        }
        cout<<res<<endl;
    }
}

 







相關文章