貪心算法
過河問題
時間限制: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>
void qsort(int num[], int l, int r)
{
if (l < r)
{
int i = l, j = r, x = num[l];
while (i < j)
{
while (i < j && num[j] >= x)
j--;
if (i < j)
num[i++] = num[j];
while (i < j && num[i] < x)
i++;
if (i < j)
num [j--] = num[i];
}
num[i] = x;
qsort(num, l, i-1);
qsort(num , i+1, r);
}
}
int main ()
{
int i, j, t, n, num[1000];
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
for (i = 0; i < n; i++)
scanf("%d", &num[i]);
qsort(num, 0, n-1); // 快排
int sum = 0;
while (n >= 4)
{
if (num[1] + num[0] + num[n-1] + num[1] < num[n-1] +num[0]+num[0]+num[n-2] )
{
// 兩個人同時接
sum += num[1]; // 最快的和第二快的過河
sum += num[0]; // 最快的回來送燈(剩下第二快的)
sum += num[n-1]; // 最慢的和第二慢的過河
sum += num[1]; // 第二塊的回去送燈
// 還有第二快的 和最快的沒回來
}
else
{
// 一個人接
sum += num[n-1]; // 最快的和最慢的過河
sum += num[0]; // 最快的回去送燈
sum += num[n-2]; // 最快的把 第二慢的接過去
sum += num[0]; // 最快的回去
//還有第二快的和最快的沒回來
}
n -= 2; // 因爲過去了兩個人 還有兩個人
}
if (n == 3)
{
sum += num[2] + num[0] + num[1];
}
if (n == 2)
{
sum += num[1];
}
if (n == 1)
{
sum += num[0];
}
printf("%d\n", sum);
}
return 0;
}