uva 10037 - Bridge(贪心)

题目链接:uva 10037 - Bridge


题目大意:有n个人要过桥,每次可以过一个或两个人,但是过桥一定要有灯,现在找出过桥最短的方案。


解题思路:送灯肯定要让速度最快的来送,所以就有了两种过桥方式。假设现在要让a[i-1]和a[i]过桥,方案1:a0 a1,a0,ai-1 ai, a1.方案2:a0 ai,a0,ai-1 a0,a0。比较两种方案的时间,取较少的。注意n为奇数的情况,最后剩3个人。


#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;

const int N = 1005;
int n, a[N];

void init() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++) scanf("%d", &a[i]);
	sort(a, a + n);
}

int solve() {
	if (n == 1) return a[0];
	else if (n == 2) return a[1];

	int ans = 0, e = n % 2 + 1;
	for (int i = n - 1; i > e; i -= 2) {
		ans += a[0] + a[i];
		if (a[1] * 2 < a[i-1] + a[0]) {
			ans += a[1] * 2;
		} else {
			ans += a[i-1] + a[0];
		}
	}
	if (n % 2) ans += a[0] + a[1] + a[2];
	else ans += a[1];
	return ans;
}

void put() {
	if (n == 1) printf("%d\n", a[0]);
	else if (n == 2) printf("%d %d\n", a[0], a[1]);
	else if (n == 3) {
		printf("%d %d\n%d\n", a[0], a[1], a[0]);
		printf("%d %d\n", a[0], a[2]);
	} else {
		int e = n % 2 + 1;
		for (int i = n - 1; i > e; i -= 2) {
			if (a[1] * 2 < a[i-1] + a[0]) {
				printf("%d %d\n%d\n", a[0], a[1], a[0]);
				printf("%d %d\n%d\n", a[i-1], a[i], a[1]);
			} else {
				printf("%d %d\n%d\n", a[0], a[i-1], a[0]);
				printf("%d %d\n%d\n", a[0], a[i], a[0]);
			}
		}
		if (n % 2) {
			printf("%d %d\n%d\n", a[0], a[1], a[0]);
			printf("%d %d\n", a[0], a[2]);

		} else printf("%d %d\n", a[0], a[1]);
	}
}

int main() {
	int cas; scanf("%d", &cas);
	while (cas--) {
		init();
		printf("%d\n", solve());
		put();
		if(cas) printf("\n");
	}
	return 0;
}


你可能感兴趣的:(uva 10037 - Bridge(贪心))