NYOJ47过河问题

reference from http://blog.csdn.net/lyhvoyage/article/details/23196933
 
//NYOJ47过河问题
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include <algorithm>
using namespace std;
int a[1005];
int total = 0;
void greedySelect(int a[], int N);
int main(void)
{
	int T, N;
//	freopen("in.txt", "r", stdin);
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d", &N);
		for(int i = 0; i < N; i++)
		{
			scanf("%d", &a[i]);
		}
		sort(a, a + N);//默认升序;
		total = 0;
		greedySelect(a, N);
		printf("%d\n", total);
	}
	return 0;
}
void greedySelect(int a[], int n)
{
	while(n >= 4)
	{
		if(2 * a[0] + a[n - 1] + a[n - 2] <  a[0] + 2 * a[1] + a[n - 1])
		{
			total += a[n - 1];
			total += a[0];
			total += a[n - 2];
			total += a[0];
		}
		else
		{
			total += a[1];
			total += a[0];
			total += a[n - 1];
			total += a[1];
		}
		n = n - 2;
	}
	if(n == 1)
		total += a[0];
	else if(n == 2)
		total += a[1];
	else
		total += a[2] + a[0] + a[1];
}
/*
a[0]:用时最短; a[1]:用时次短;
a[n - 1]:用时最长, a[n - 2]用时次长;
(1)有n = 1个人时:
直接过河;
(2)有n = 2个人时:
total = a[1];
(3)有n = 3个人时:
total = a[2] + a[0] + a[1];
(4)有n >= 4个人时:
有下面两种方案过河:
方案一:
用时最短的a[0]和用时最长的a[n - 1]先过河, 用时最短的a[0]回来;
然后用时最短的a[0]和用时次长的a[n - 2]过河, 用时最短的a[0]回来;(注意not用时次短的a[1]和用时次长的a[n - 2]过河, 用时次短的a[1]回来)
最后就剩下两个人了。
a[n - 1] + a[0] + a[n - 2] + a[0] = 2a[0] + a[n - 1] + a[n - 2];
方案二:
用时最短的a[0]和用时次短的a[1]先过河, 用时最短的a[0]回来;
然后用时最长的a[n - 1]和用时次长的a[n - 2]过河, 用时次短的a[1]回来;
最后就剩下两个人了。
a[1] + a[0] + a[n - 1] + a[1] = a[0] + 2a[1] + a[n - 1]。
相当于对(n - 2)个人执行相同的操作,计算比较上面两种方案的结果,取最好的。

*/        

你可能感兴趣的:(NYOJ47过河问题)