UVA-10037 Bridge---过河问题进阶版(贪心)

时间:2023-03-09 01:55:26
UVA-10037 Bridge---过河问题进阶版(贪心)

题目链接:

https://vjudge.net/problem/UVA-10037

题目大意:

N个人夜里过河,总共只有一盏灯,每次最多过两个人,然后需要有人将灯送回

才能继续过人,每个人过桥都需要耗费一定的时间,让你求耗费的最少时间,并输出过河方案

思路:

和之前POJ-1700一样,不过这里要求输出每次过河的人,所以先算出答案之后在来一遍输出路径

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int T, n;
int a[];
int main()
{
cin >> T;
while(T--)
{
cin >> n;
for(int i = ; i < n; i++)cin >> a[i];
sort(a, a + n);
int i, tot = , sum = ;
for(i = n - ; i >= ; i -= )//小于三人单独讨论
{
//策略一:最快的和次快的先过河(时间a[1]),然后最快的回来送灯(a[0]),最慢的和次慢的过河a[i],然后次快的回来送灯a[1];
int t1 = a[] + * a[] + a[i];
//策略二:由最快的和最慢的过河(时间a[i]),然后最快的回来送灯(a[0]),次慢的和最慢的过河a[i-1],然后最快的回来送灯a[0];
int t2 = * a[] + a[i - ] + a[i];
sum += min(t1, t2);
}
int cases;
if(i == )sum += a[] + a[] + a[], cases = ;
else if(i == )sum += a[], cases = ;
else sum += a[], cases = ;
printf("%d\n", sum);
for(int i = n - ; i >= ; i -= )
{
int t1 = a[] + * a[] + a[i];
int t2 = * a[] + a[i - ] + a[i];
if(t1 > t2)
{
printf("%d %d\n", a[], a[i]);
printf("%d\n", a[]);
printf("%d %d\n", a[], a[i - ]);
printf("%d\n", a[]);
}
else
{
printf("%d %d\n", a[], a[]);
printf("%d\n", a[]);
printf("%d %d\n", a[i - ], a[i]);
printf("%d\n", a[]);
}
}
if(cases == )printf("%d\n", a[]);
else if(cases == )printf("%d %d\n", a[], a[]);
else
{
printf("%d %d\n", a[], a[]);
printf("%d\n", a[]);
printf("%d %d\n", a[], a[]);
}
if(T)cout<<endl;
}
return ;
}