過河問題
時間限制: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; } }