Gone Fishing(Poj1042)(贪心+枚举)

本文介绍了一个名为GoneFishing的问题解决方案,通过贪心算法加枚举的方法来帮助John规划他的钓鱼行程,使其在有限时间内捕获最多的鱼。文章详细解释了题目的背景及解决思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Gone Fishing
Time Limit: 2000MS Memory Limit: 32768K
Total Submissions: 31703 Accepted: 9588

Description

John is going on a fishing trip. He has h hours available (1 <= h <= 16), and there are n lakes in the area (2 <= n <= 25) all reachable along a single, one-way road. John starts at lake 1, but he can finish at any lake he wants. He can only travel from one lake to the next one, but he does not have to stop at any lake unless he wishes to. For each i = 1,...,n - 1, the number of 5-minute intervals it takes to travel from lake i to lake i + 1 is denoted ti (0 < ti <=192). For example, t3 = 4 means that it takes 20 minutes to travel from lake 3 to lake 4. To help plan his fishing trip, John has gathered some information about the lakes. For each lake i, the number of fish expected to be caught in the initial 5 minutes, denoted fi( fi >= 0 ), is known. Each 5 minutes of fishing decreases the number of fish expected to be caught in the next 5-minute interval by a constant rate of di (di >= 0). If the number of fish expected to be caught in an interval is less than or equal to di , there will be no more fish left in the lake in the next interval. To simplify the planning, John assumes that no one else will be fishing at the lakes to affect the number of fish he expects to catch. 
Write a program to help John plan his fishing trip to maximize the number of fish expected to be caught. The number of minutes spent at each lake must be a multiple of 5.

Input

You will be given a number of cases in the input. Each case starts with a line containing n. This is followed by a line containing h. Next, there is a line of n integers specifying fi (1 <= i <=n), then a line of n integers di (1 <=i <=n), and finally, a line of n - 1 integers ti (1 <=i <=n - 1). Input is terminated by a case in which n = 0.

Output

For each test case, print the number of minutes spent at each lake, separated by commas, for the plan achieving the maximum number of fish expected to be caught (you should print the entire plan on one line even if it exceeds 80 characters). This is followed by a line containing the number of fish expected. 
If multiple plans exist, choose the one that spends as long as possible at lake 1, even if no fish are expected to be caught in some intervals. If there is still a tie, choose the one that spends as long as possible at lake 2, and so on. Insert a blank line between cases.

Sample Input

2 
1 
10 1 
2 5 
2 
4 
4 
10 15 20 17 
0 3 4 3 
1 2 3 
4 
4 
10 15 50 30 
0 3 4 3 
1 2 3 
0 

Sample Output

45, 5 
Number of fish expected: 31 

240, 0, 0, 0 
Number of fish expected: 480 

115, 10, 50, 35 
Number of fish expected: 724 


    说实话这道题我看了很久也没看懂这道是什么意思,主要还是英语太渣,于是也是看了他人博客才知道题意。
题目大意:就是说一个人在一个打算在编号1~n的湖里钓鱼,钓鱼是单向走的,不能往回走。给你n个湖,每个湖初始鱼的数量pi
每次每个湖钓鱼后鱼的减少量di,第i个湖到第i+1湖的距离时间ti(单位是5min),这个人可以在任何湖停止钓鱼
求如何钓鱼才能才能在h小时内钓鱼量最多输出在每个湖钓鱼的时间。相同钓鱼量情况下,输出湖编号小的用时多的时间。

思想就是:用贪心+枚举即可。 因为钓鱼是单向进行的,可以在任何湖停止钓鱼,我们可以先减去在路上走路的时间,剩下的
时间就是钓鱼的时间,然后我们枚举出分别以1~n为结束钓鱼时的情况。每次找出当前情况下钓鱼量最多的湖进行钓鱼,在不超
过钓鱼时间的情况下,继续上述操作。再从以1~n为结束钓鱼时的钓鱼最大量!

注意:我们在减去在路上的时间后,剩下的即在钓鱼的时间,之后我们可以看做在不超过结束钓鱼的湖 进行瞬间移动。

总之第一次做这么巧妙的贪心,感觉还是做得题太少了。还有一点在poj提交时G++AC,C++要么WA,要么CE不知道为什么。。。

代码:
#include<stdio.h>
int fi[30];
int di[30];
int ti[30];
int cfi[30];
int h,n;
struct st
{
	int max;
	int num[30];
}lake[30];
int getmax(int p[],int i,int j)
{
	int l=i,max=p[i];
	for(int m=i+1;m<=j;m++)
	{
		if(max<p[m])
		{
			max=p[m];
			l=m;
		}
	}
	return l;
}
int getfish()
{
	for(int i=1;i<=n;i++)
	{
		lake[i].max=0;
		for(int j=1;j<=n;j++)
		{
			lake[i].num[j]=0;
		}
	}
	for(int i=1;i<=n;i++)//i表示结束钓鱼时的湖序号 
	{
		int t=0;
		int T=h*60;
		for(int j=1;j<=i;j++)
		{
			cfi[j]=fi[j];
			if(j<i)
			T=T-ti[j]*5;
		}
		while(t<T)
		{
			int k=getmax(cfi,1,i);//找到当前情况下,钓鱼量最大的湖进行钓鱼 
			lake[i].num[k]+=5;
			lake[i].max+=cfi[k];
			cfi[k]=(cfi[k]>di[k])?cfi[k]-di[k]:0;
			t+=5;
		}
	}
	for(int i=1;i<=n;i++)//找出钓鱼量最多下标,即为结束钓鱼的湖序号 
	{
		cfi[i]=lake[i].max;
	}
	int l=getmax(cfi,1,n);
	for(int i=1;i<=n;i++)
	{
		if(i!=n)
			printf("%d, ",lake[l].num[i]);
		else
			printf("%d\n",lake[l].num[i]); 
	}
	printf("Number of fish expected: %d\n\n",lake[l].max);
}
int main()
{
	while(scanf("%d",&n),n)
	{
		scanf("%d",&h);
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&fi[i]);
		}
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&di[i]);
		}
		for(int i=1;i<n;i++)
		{
			scanf("%d",&ti[i]);
		}
		getfish(); 
	}
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值