POJ1700 Crossing River(貪心算法訓練)


Time Limit: 1000MS          Memory Limit: 10000K          Total Submissions: 13301          Accepted: 5087

Description

A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the boat back and forth so that all people may cross. Each person has a different rowing speed; the speed of a couple is determined by the speed of the slower one. Your job is to determine a strategy that minimizes the time for these people to get across.

Input

The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. The first line of each case contains N, and the second line contains N integers giving the time for each people to cross the river. Each case is preceded by a blank line. There won't be more than 1000 people and nobody takes more than 100 seconds to cross.

Output

For each test case, print a line containing the total number of seconds required for all the N people to cross the river.

Sample Input

1
4
1 2 5 10

Sample Output

17

 

一、題目大意

      有N個人要渡河,但是只有一艘船,船上每次最多只能載兩個人,渡河的速度由兩個人中較慢的那個決定,小船來回載人直到所有人都渡河,求最短的渡河時間。

 

二、解題思路

      一開始的時候忘了需要有一個人將小船撐回起點,所以簡單的對N個人進行排序,從小到大兩個人為一組,依次渡河,顯然答案是錯誤的。習慣性眼瞎是病得治QAQ。假如考慮需要回程的情況,那么每一次都需要讓在終點渡河最快的人把船撐回,所以需要保證終點有速度快的人能夠把船撐回起點,顯然一開始的思路時間不是最短。假設有速度最快的人a、速度次快的人b,速度最慢的人c,速度次慢的人d,把c和d送到終點考慮兩種策略

▶1、 a和b出發,a回來,c和d出發,b回來

▶2、 a和c出發,a回來,a和d出發,a回來

只需要比較這兩種策略的快慢,每次選擇較快的策略,當起點的人數少於4時直接處理,即可得出結果。

 

三、具體代碼  

 1 // greedy algorithm
 2 #include <cstdio>
 3 
 4 int MIN_(int a, int b){
 5     if(a>b) return b;
 6     else return a;
 7 }
 8 
 9 int main(){
10     int t, n, tmp, speed[1005];
11     scanf("%d", &t);
12     while(t--){
13         scanf("%d", &n);
14         for(int i=0; i<n; i++){
15             scanf("%d", &speed[i]);
16         }
17         // bubble sort(0->n:small->large)
18         for(int i=0; i<n; i++){
19             for(int j=i; j<n; j++){
20                 if(speed[i] > speed[j]){
21                     tmp = speed[i];
22                     speed[i] = speed[j];
23                     speed[j] = tmp;
24                 }
25             }
26         }
27         // greedy
28         int start = n, ans = 0;
29         while(start){
30             // start = 1,2,3時直接處理 
31             if(start == 1){
32                 ans  += speed[0];
33                 break; 
34             }
35             else if(start == 2){
36                 ans += speed[1];
37                 break;
38             }
39             else if(start == 3){ // 0,2過河,0回程,0,1過河 
40                 ans += speed[2]+speed[0]+speed[1];
41                 break;
42             }
43             // start>3根據策略選擇 
44             else{
45                 ans += MIN_(speed[1]+speed[0]+speed[start-1]+speed[1], speed[start-1]+2*speed[0]+speed[start-2]);
46                 start -= 2; 
47             } 
48         } 
49         printf("%d\n", ans);
50     }
51     
52     return 0;
53 } 
View Code

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM