過河問題時間限制:1000 ms | 記憶體限制:65535 kb
難度:5
描述在漆黑的夜裡,n位旅行者來到了一座狹窄而且沒有護欄的橋邊。如果不借助手電筒的話,大家是無論如何也不敢過橋去的。不幸的是,n個人一共只帶了乙隻手電筒,
而橋窄得只夠讓兩個人同時過。如果各自單獨過橋的話,n人所需要的時間已知;而如果兩人同時過橋,所需要的時間就是走得比較慢的那個人單獨行動時所需的時間。
問題是,如何設計乙個方案,讓這n人盡快過橋。
輸入第一行是乙個整數t(1<=t<=20)表示測試資料的組數
每組測試資料的第一行是乙個整數n(1<=n<=1000)表示共有n個人要過河
每組測試資料的第二行是n個整數si,表示此人過河所需要花時間。(0
輸出輸出所有人都過河需要用的最少時間
樣例輸入
1 4 1 2 5 10
樣例輸出
17----------
對於時間排序得到s(1) <= s(2) .... s(n-1) <= s(n)
/*貪心遞迴式:
首先由題目已知,無論單獨過橋,還是兩人一起過橋均需要手電筒,顯然,當剩餘未過橋的人數n > 1 ,是必定要兩個一起過橋的,但過橋後,仍需要乙個人送回手電筒,
顯然送手電筒的人必須用時較短,因此我們選擇s(1)送手電筒,而兩個人一起過橋,顯然為了用時最短,我們需要將剩餘未過橋n人中用時最長的兩個人s(n),s(n- 1)
先過橋,然後讓s(1)送手電筒,但現在問題在於,由於只有乙個手電筒,所以,讓p,q先過橋顯然是不合理的,因為過橋後仍需送回手電筒,這就要求在p,q過橋之前,
s(1)到達橋對面。
但我們再深入思考一下,若只讓s(1)一人先過橋,然後再送回手電筒,顯然也是不合理的,因為s(n - 1),s(n)過橋後,無人留在橋對面送回手電筒(我們盡量不讓
時間較長的s(n - 1)和s(n - 1)送回手電筒),所以需要s(1)和s(2)一起過橋,然後s(1)送回手電筒,讓s(n - 1)和s(n)過橋後,再由s(2)送回。以此類推。
這時,第一種方案出來了,即:sum1 = s(1) + 2 * s(2)+ s(n);
但我們再仔細分析可以發現,在這個方案中,s(1)必定存在,但由於具有2 * s(2),若s(2)相對較大時,(這是可能的,因為當剩餘的人越來越少時,過橋時間越來越
接近)此時,第二種方案可能比第一種方案所需時間較短,即 sum2 = 2 * s(1) + s(n - 1) + s(n);此時,s(1)和s(n),s(n - 1)一起過橋,且返回2次,我們可
以用sum2 - sum1 = s(1) + s(n - 1) - 2 * s(2);當s(1) + s(n - 1) < 2 * s(2)時方案二較優。
因此我們可得方程式:
sum = sum + min(s(n - 1) + 2 * s(1) + s(n),s(n) + s(1) + 2 * s(2))
*/----------
#include
#include
#define min(a,b) ((a) > (b) ? (b) :(a))
int cmp(const void *a, const void *b)
int main()
qsort(s, i, sizeof(s[1]), cmp);
int sum = 0;
while (n > 3)
if (n == 3)
sum = sum + s[1] + s[2] + s[3];
else if (n == 2)
sum = sum + s[2];
else
sum = sum + s[1];
printf("%d\n", sum);
}return 0;
}
貪心 過河問題
時間限制 1000 ms 記憶體限制 65535 kb 難度 5 描述 在漆黑的夜裡,n位旅行者來到了一座狹窄而且沒有護欄的橋邊。如果不借助手電筒的話,大家是無論如何也不敢過橋去的。不幸的是,n個人一共只帶了乙隻手電筒,而橋窄得只夠讓兩個人同時過。如果各自單獨過橋的話,n人所需要的時間已知 而如果兩...
貪心 過河問題
題目意思 每個人過河都有自己的過河時間,有n個人想過河,但只有乙隻小船,最多只能裝2個人,每一次過河,過河時間為用時最多的那人過河時間,如果還有人沒有過河,那麼過去乙個用時最少 的送回船。問n人過河最少要多少時間。分析 參考網上的思路 題意 也就是乙個坐船問題,一共有兩個策略 最快和次快過去,最快回...
過河問題(貪心)
時間限制 1000 ms 記憶體限制 65535 kb 難度 5 描述 輸入第一行是乙個整數t 1 t 20 表示測試資料的組數 每組測試資料的第一行是乙個整數n 1 n 1000 表示共有n個人要過河 每組測試資料的第二行是n個整數si,表示此人過河所需要花時間。0輸出 輸出所有人都過河需要用的最...