题目大意:N个人要过河,只有一个蜡烛且只有一条船,船每次最多坐2个人。不管怎样,过河者(1个人或者2个人)都必须有蜡烛,所以过河后可能需要人返回送蜡烛,然后再继续过河。问怎样过河时间最短。
解题思路:贪心,先把时间从小到大排列。
考虑N等于1时,就是一个人过河的时间,N等于2时,为两个人的最大时间,N等于3是,为最小和次小过去,最小回来,然后最小和最大时间过去,总时间为T[0] + T[1] + T[2];
考虑N大于3,考虑排在最后两个人的两种情况,
1.最小时间和次小时间的人先过去,然后最小小时间的人回来,然后最长时间和次长时间的人过去,最次小时间的人回来,总时间为T[1] + T[0] + T[N-1] + T[1];
2.最小时间和最长时间的人过去,最小时间的人回来,然后最小时间的人和次长时间的人过去,最小时间的人回来
总时间为T[N-1] + T[0] + T[N - 2] + T[0];
取两者的最小值,问题规模减少了2个人,然后继续求解。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1010;
int cost[maxn], n, t;
int main()
{
scanf("%d", &t);
while(t-- != 0)
{
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d", &cost[i]);
sort(cost, cost + n);
int s = 0;
while(true)
{
if(1 == n)
{
s += cost[0];
break;
}
else if(2 == n)
{
s += cost[1];
break;
}
else if(3 == n)
{
s += cost[0] + cost[1] + cost[2];
break;
}
else
{
int t1 = cost[1] + cost[0] + cost[n - 1] + cost[1];
int t2 = cost[n - 1] + cost[0] + cost[n - 2] + cost[0];
s += min(t1, t2);
}
n -= 2;
}
printf("%d\n", s);
}
return 0;
}