贪心算法
过河问题
时间限制: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;
}