POJ 1042 Gone Fishing

题意:


2 
1 
10 1 
2 5 
2 
意思是有两个湖,有一个小时的时间让你钓鱼

第一个湖泊初始5分钟能钓10个,每过5分钟能钓的鱼减1

第二个湖泊初始5分钟能钓2个,每过5分钟能钓的鱼减5,少于0就是0

从第一个湖泊到第二个湖泊的时间为2*5分钟

你只能在一个湖泊钓鱼,然后走到下一个湖泊,不允许回头

解法:

枚举到达的最后一个湖泊,则已知将会在哪些湖泊钓鱼以及路上花费时间

每次取能获得最大收益的湖泊钓鱼,即为答案

注意:

在收益相同时,在0号湖泊钓的时间长的为最优,若0号相同,则1号,2号。。。

代码:

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
class T
{
public:
	int f;
	int d;
	int t;
}lake[30];//0,1,,,,n-1
int n,h;
int num[30];
class U
{
public:
	int gains;
	int time[30];
}ans;
bool operator>(U a,U b)
{
	if(a.gains==b.gains)
	{
		for(int i=0;i<n;i++)
		{
			if(a.time[i]==b.time[i])
			{
				continue;
			}
			return a.time[i]>b.time[i];
		}
	}
	return a.gains>b.gains;
}
struct cmp
{
	bool operator()(int i,int j)
	{
		int mi=lake[i].f-lake[i].d*num[i];
		if(mi<0)
		{
			mi=0;
		}//mi表示在i湖泊钓鱼所得
		int mj=lake[j].f-lake[j].d*num[j];
		if(mj<0)
		{
			mj=0;
		}
		if(mi==mj)//收获相同时序号小优先
		{
			return i>j;
		}
		return mi<mj;
	}
};
void solve(int m,int h)//0,1,,,m号湖泊
{
	int counter=0;
	priority_queue<int,vector<int>,cmp>Q;//湖泊序号的优先队列
	for(int i=0;i<=m;i++)
	{
		Q.push(i);
	}
	for(int i=0;i<=m-1;i++)
	{
		h-=lake[i].t;
	}
	while(h>0&&!Q.empty())
	{
		int tmp=Q.top();//取出当前获得最大值的湖泊序号
		Q.pop();
		counter+=(lake[tmp].f-num[tmp]*lake[tmp].d)>0?(lake[tmp].f-num[tmp]*lake[tmp].d):0;
		num[tmp]++;
		h-=5;
		Q.push(tmp);
	}
	if(h>0)
	{
		num[0]+=h/5;
	}
	U ant;
	for(int i=0;i<=m;i++)
	{
		ant.time[i]=num[i]*5;
	}
	for(int i=m+1;i<n;i++)
	{
		ant.time[i]=0;
	}
	ant.gains=counter;
	if(ant>ans)
	{
		ans=ant;
	}
}
int main()
{
	while(scanf("%d",&n),n)
	{
		ans.gains=-1;
		scanf("%d",&h);
		h*=60;//换成分钟
		for(int i=0;i<n;i++)
		{
			scanf("%d",&lake[i].f);
		}
		for(int i=0;i<n;i++)
		{
			scanf("%d",&lake[i].d);
		}
		for(int i=0;i<n-1;i++)
		{
			scanf("%d",&lake[i].t);
			lake[i].t*=5;
		}
		for(int i=0;i<n;i++)//最后到达的是i号湖泊
		{
			if(i==n-1)
			{
				i=n-1;
			}
			memset(num,0,sizeof(num));//每个湖泊已经钓鱼过的次数
			solve(i,h);
		}
		for(int i=0;i<n-1;i++)
		{
			printf("%d, ",ans.time[i]);
		}
		printf("%d\n",ans.time[n-1]);
		printf("Number of fish expected: %d\n\n",ans.gains);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值