poj-1700-Crossing River **

/*
* poj-1700-Crossing River.cpp
*
*贪心:
* 最佳方案构造法:以下是构造N个人(N≥1)过桥最佳方案的方法:
* 1) 如果N=1、2,所有人直接过桥。
* 2) 如果N=3,由最快的人往返一次把其他两人送过河。
* 3) 如果N≥4,设A、B为走得最快和次快的旅行者,过桥所需时间分别为a(1)、a(2);而Z、Y为走得最慢和次慢的旅行者,
* 过桥所需时间分别为a(n-1)、a(n)。
* 易知:a(n)是肯定会出现在计算cost的和式中的,考虑把a(n)和a(n-1)带过桥:
* 方案一 : a(1),a(2)过去 ---- a(1)回来 ----- a(n-1),a(n)过去 ---- a(2)回来
* 方案二 : a(1)a(n)过去-----a(1)回来------a(1)a(n-1)回来----a(1)回来
*
* 比较哪个用时少就用哪个方案, 这样就把最慢的两个送过去了, 问题规模变为n-2,,递归解决。。
*
*/
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxN = 1000 + 5;

int t, n, cost[maxN];

int greedy(){
int left = n, totCost = 0;
while(left > 3){
if(cost[1] + cost[left - 1] < 2 * cost[2])
totCost += cost[1] * 2 + cost[left-1] + cost[left];
else
totCost += cost[1] + cost[2] * 2 + cost[left];

left -= 2;
}
if(left == 3)
totCost += cost[1] + cost[2] + cost[3];
else if(left == 2)
totCost += cost[2];

return totCost;
}

int main(){
scanf("%d", &t);
while(t--){
scanf("%d", &n);
for(int i=1; i<=n; i++)
scanf("%d", &cost[i]);

sort(cost, cost + n);

if(n == 1) //别忘了n==1的情况!!
printf("%d\n", cost[1]);
else
printf("%d\n", greedy());
}

return 0;
}

你可能感兴趣的:(poj)