POJ-1042 Gone Fishing 【贪心】【优先队列】

题目链接:https://cn.vjudge.net/problem/OpenJ_Bailian-1042

题意:John有h个小时的钓鱼时间,一共有n个湖泊,它们在一条直线上。从第1个湖开始,可以在任意一个湖停下,每到达一个湖,这个湖开始有f[i]条鱼,钓一次鱼需要5分钟,5分钟后这个湖的鱼的数量为上次数量减去d[i],并且从第i个湖到第i+1个湖需要ti*5的时间。如果某个时间段期望钓到的鱼数小于或者等于di,那么下一个时间段湖中将不再有鱼剩下。为了简化计划,John假设没有其他钓鱼人影响到他的钓鱼数目。目标是让他能钓到的鱼最多。在每个湖他所花的时间必须是5分钟的倍数。

分析:为了叙述方便,把钓5分钟鱼称为钓一次鱼。首先枚举John需要走过的湖泊数X,也就是假设他从湖泊1走到湖泊X,在湖泊X停止钓鱼,则路上花去的时间记为time[X]。在这个前提下,可以认为John能从一个湖“瞬间转移”到另一个湖,那么在任意一个时刻都可以从湖泊1到湖泊X中任选一个湖泊来钓鱼。因此,采取贪心策略,每次选一个鱼最多的湖泊来钓鱼。对于每个湖泊而言,由于在任何时候鱼的数量之和John在该湖钓鱼的次数有关,而和钓鱼的总次数无关,所以这个策略是最优的。假设一共允许钓k次鱼,那么每次在n个湖泊中选择鱼最多的一个湖泊钓,选择每次钓鱼地点的时间复杂度为O(n),总的时间复杂度为O(n^2)。如果用优先队列来做,总的时间复杂度可以降为O(nlogn)。


题意/分析-原作者:lyhvoyage 
原文:https://blog.csdn.net/LYHVOYAGE/article/details/23289531 
 

AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
const int maxn = 31;
struct Pond
{
	int order,f,d;
	friend bool operator < (const Pond &t1,const Pond &t2) {
		if(t1.f == t2.f)
			return t1.order > t2.order;
		return t1.f < t2.f;
	}
}Ponds[maxn];
int dis[maxn];
int times[maxn][maxn];  //  times[i][j]记录最多走到i池塘时,第j个池塘的停留时间
int main()
{
	int n,T;

	while(scanf("%d",&n) && n) {
		scanf("%d",&T);
		T = T*12;
		for(int i=1;i<=n;i++) {
			scanf("%d",&Ponds[i].f);
			Ponds[i].order = i;
		}
		for(int i=1;i<=n;i++)
			scanf("%d",&Ponds[i].d);
		for(int i=1;i<n;i++)
			scanf("%d",&dis[i]);
		
		memset(times,false,sizeof times);
		int MaxFish = 0;
		int MaxPond = 1;		
		// 最多走到第MaxPond个鱼塘  注意,初始化一定为1,因为若果所有鱼塘初始鱼量都为0,
		// 那么后续对MaxPond的操作都不会进行,实际是John要一直在第一个鱼塘愣着啥也不干
		int MaxFish_t;
		int t;
		for(int i=1;i<=n;i++) {		// 当最多走到第i个鱼塘
			t = T;	
			priority_queue<Pond> P;
				for(int j=1;j<=i;j++)				
						P.push(Ponds[j]);
 			for(int j=1;j<i;j++) 
				t -= dis[j];		// 出去跑路还剩下的时间 单位:(5min)
			MaxFish_t = 0;
			Pond temp;
			for(int j=1;j<=t;j++) {
				temp = P.top();	
				MaxFish_t += temp.f;
				temp.f = max(temp.f - temp.d,0);
				times[i][temp.order]++;
				P.pop();
				P.push(temp);
			}
			if(MaxFish_t > MaxFish) {
				MaxFish = MaxFish_t;
				MaxPond = i;
			}
		}
		for(int i=1;i<n;i++)
			printf("%d, ",times[MaxPond][i]*5);
		printf("%d\n",times[MaxPond][n]*5);
		printf("Number of fish expected: %d\n\n", MaxFish);
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_42765557/article/details/84930293
今日推荐