POJ 1700-Crossing River(贪心)

Crossing River

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 24945 Accepted: 9155

Description

A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the boat back and forth so that all people may cross. Each person has a different rowing speed; the speed of a couple is determined by the speed of the slower one. Your job is to determine a strategy that minimizes the time for these people to get across.

Input

The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. The first line of each case contains N, and the second line contains N integers giving the time for each people to cross the river. Each case is preceded by a blank line. There won’t be more than 1000 people and nobody takes more than 100 seconds to cross.

Output

For each test case, print a line containing the total number of seconds required for all the N people to cross the river.

Sample Input

1
4
1 2 5 10

Sample Output

17

题目描述
UCAS_ACM小组的N名成员外出旅游,结果在路上碰到了一条河,岸边只有一艘船,这艘船最多只能载两人。
已知N名成员每人有一个过河时间ti,每次划船过河的时间等于船上成员的过河时间的最大值。请你找N名成员全部到底对岸的最少耗时。
输入
输入包含多组测试数据。第一行含有一个正整数T,表示数据组数。
每组数据的第一行含有一个整数N。接下来的一行含有N个整数,表示ti。
输出
对于每组输入数据输出一行,每行包括1个整数,代表该组数据下到对岸的最少耗时。
样例输入
2
4
1 2 5 10
5
1 2 8 7 6
样例输出
17
22
数据范围
1≤T≤20
1≤N≤1000
1≤ti≤100
提示
船划到对岸后不会自动飘回来的哦~

题目大意:给出T组测试样例,对于每组测试样例,给出n个人的划船速度,求所有人过河所用的最短时间。

解题思路:这道题用到贪心的思想,我们可以用一个数组来存每个人的过河速度,然后从小到大排序。我们需要考虑到4种情况:第一种:没有过河的人>=4,我们每次只带最慢和次慢的人过河。第二种:没过河的人==3,三个人最后全部过河。第三种:没过河的人有1人或者2人,全部过河。
情况一有两种可能:

  • 最快的人带最慢的人过去,最快的回来,再带次慢的过河,因为每次要送走最慢和次慢,最轻的再回来,时间为:a[n]+a[1]+a[n-1]+a[1];
  • 最快的和次快的人过河,最快的回来,最慢和次慢的过河,次快的回来。时间为:a[2]+a[1]+a[n]+a[2];
  • 因为要求最短时间,所以我们这两种取最短的时间即可。
    情况二:
    最快的带最慢的,最快的回来,再带次慢的,最快的再过河,三个人全过去。时间:a[n]+a[1]+a[n-1];
    情况三:当没过河的人只有一人或两人,一定是最快的和次快的,两人一起过河。时间a[2];
    AC代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int _max=1e3+50;
int a[_max];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		int ans=0;
		for(int i=1;i<=n;i++)
		  cin>>a[i];
		while(n>0)
		{
			if(n>=4)
			{
				int sum1=2*a[1]+a[n]+a[n-1];
				int sum2=2*a[2]+a[1]+a[n];
				ans+=min(sum1,sum2);//取最小
				n-=2;
			}
			else if(n==3)
			  ans+=(a[1]+a[2]+a[n]),n=0;
			else if(n<=2)
			  ans+=a[n],n=0;
		}
		cout<<ans<<endl;
	}
	//system("pause");
	return 0;
}
原文地址:https://www.cnblogs.com/Hayasaka/p/14294295.html