贪心算法:小船过河问题

【Description】
一群人划船过河,河边只有一条船,这条船可以容纳两个人,船过河后需要一人将船开回,以便所有人都可以过河,每个人过河速度不一样,两个人过河速度取决于慢的那个人,请问最少需要多久让所有人过河?
【Input】
第一行输入人数n;
第二行输入每个人过河所需的时间;
【Output】
输出需要的最少时间
【Sample Input】
4
1 2 5 10
【Sample Output】
17
题目分析:
两种方法,较容易想到的是第一种方式:
第一种办法:先让1 2过去(2分钟),1回来(1分钟),1 5过去(5分钟),1回来(1分钟),1 10再过去(10分钟),总共需要19分钟就可以让四个人都过去。

而正确答案是第二种办法:先让1 2过去(2分钟),1回来(1分钟),5 10过去(10分钟),2回来(2分钟),1 2再过去(2分钟),总共需要17分钟就可以让四个人都过去。

本题的关键在于把最慢的和次慢的两个人运过河,因此只要大于四个人的情况下:只需要将这两种方式这两个人运过河的时间做对比:
第一种:T4+T1+T3+T1
第二种:T2+T1+T4+T2
对比之后取短的就行

源码如下:

#include<iostream>
#include<algorithm>
using namespace std;

/*void swap(int a[],int x,int y)
{
	int temp=a[x];
	a[x]=a[y];
	a[y]=temp;
}

int Getpoint(int a[],int low,int high)
{
	int point=a[low];
	while(low<high)
	{
		while(low<high && a[high]>=point)
			high--;
		swap(a,low,high);
		while(low<high && a[low]<=point)
			low++;
		swap(a,low,high);
	}
	return low;
}

void Quick(int a[],int low,int high)
{
	if(low<high)
	{
		int point=Getpoint(a,low,high);
		Quick(a,low,point-1);
		Quick(a,point+1,high);
	}
}*/

int Cross(int a[],int n)
{
	sort(a,a+n);//这里运用了内部的排序 想提升时间可以运用快排 上面的代码是快排
	int time=0;
	while(n>3)//负责减最慢和次慢的人运过河
	{
		if( (2*a[0]+a[n-2]+a[n-1])<=(2*a[1]+a[0]+a[n-1]) )
			time=time+2*a[0]+a[n-2]+a[n-1];
		else                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
			time=time+2*a[1]+a[0]+a[n-1];
		n=n-2;//运过去两个人
	}
	if(n==3)
		time=time+a[0]+a[1]+a[n-1];
	if(n==2)
		time=time+a[n-1];
	if(n==1)
		time=time+a[0];
	return time;	
}


int main()
{
	int n;//输入一共多少个人过河
	cin>>n;
	int a[255];
	memset(a,0,sizeof(a));//初始化
	for(int i=0;i<n;i++)
		cin>>a[i];//输入每个人过河的时间
	cout<<Cross(a,n)<<endl;
	return 1;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值