POJ1042 Gone Fishing

         本题的大意是:佳佳要钓鱼,有h个小时,n个湖,每个湖初始的状态是fi,每5分钟的钓鱼,fi要减少di的鱼数,并且从i-1个湖到i湖所需的时间为ti。佳佳如何安排才能钓到最多的鱼。

          刚开始做这题时,并没有想到用贪心算法。而是通过对每一时刻t,选择是停留在该湖还是去下一个湖 ,这样可以用DP求得,d(i,n,k)表示在i时候,n湖,湖中鱼的数量为k时能取得的最大鱼数,但是这个状态有一个问题,那就是k是可以为负数的,为了记录此状态,k必须取很大,这样肯定是空间超了,而且此法虽然求最大值比较方便,但是,统计各个湖的信息比较麻烦。没办法了,只能用别的法子。网上有两个法子:DP和贪心。DP的话状态定义是d(i,j),表示在i湖停留j时间能取得的最大鱼数,由于这个我没用这个法子,就不多谈了。还有就是贪心算法,评论里面都说是黑书贪心算法的例题,里面主要说的是先统计从第1个湖到第i个湖的总时间,这样对于1到i湖之间的湖都可以认为瞬时就到了,这样的话,每次去最大的湖中钓鱼这样可以的到1到i个湖中能钓到的最大的鱼数。从1到n枚举i,就能得到最多的鱼数。


#include <stdio.h>
#include <string.h>

int n,totalTime;
int fi[26];
int di[26];
int ti[26];
int spendtime[26];
int temp[26];
int path[26]; //记录每个湖停留的时间
int fishes[26]; //用于存放每个湖的鱼数

int main()
{
	int h;
	int i,j;
	int lt,sum,index,max,result,r_max;
	
	freopen("test.txt","r",stdin);

	while(1)
	{
		sum=0;
		spendtime[0]=0;
		r_max=0;

		scanf("%d",&n);
		if(n==0)
			break;
		scanf("%d",&h);
		totalTime=12*h;
		for(i=0;i<n;i++)
			scanf("%d",&fi[i]);
		for(i=0;i<n;i++)
			scanf("%d",&di[i]);
		for(i=0;i<n-1;i++)
		{
			scanf("%d",&ti[i]);
			sum+=ti[i];
			spendtime[i+1]=sum;
		}

		for(i=0;i<n;i++)
		{
			memcpy(fishes,fi,sizeof(fi));
			memset(temp,0,sizeof(temp));

			lt=totalTime-spendtime[i];

			result=0;

			while((lt--)>0)
			{
				max=0;
				index=0;
				for (j=0;j<=i;j++)
				{
					if(fishes[j]>max)
					{
						max=fishes[j];
						index=j;
					}
				}
				temp[index]++;
				if(fishes[index]>=0)
				{
					result+=fishes[index];
					fishes[index]-=di[index];
				}
			}

			if(i==0 || r_max<result)  //注意这里必须是小于,能保证尽量在序号小的湖停留
			{
				memcpy(path,temp,sizeof(temp));
				r_max=result;
			}
		}

		for(j=0;j<n-1;j++)
		   printf("%d, ",path[j]*5);
		printf("%d\n",path[j]*5);
		printf("Number of fish expected: %d\n",r_max);
		printf("\n");
	}
	return 0;
}

     程序没有优化过,不过希望起一个抛装引玉的作用。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值