poj1042 2010.3.5

poj1042 2010.3.5

Poj 1042  Gone Fishing

 

【关键字】

枚举+贪心

【摘要】

john在规定的时间内,在给定的几个湖里钓鱼。鱼会随着时间的减少而减少。

【正文】

1、题目描述

Gone Fishing

Time Limit: 2000MS Memory Limit: 32768K

Total Submissions: 14236  Accepted: 3947

Description

John is going on a fishing trip. He has hhours 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 atlake 1, but he can finish at any lake he wants. He can only travel from onelake to the next one, but he does not have to stop at any lake unless he wishesto. For each i = 1,...,n - 1, the number of 5-minute intervals it takes totravel from lake i to lake i + 1 is denoted ti (0 < ti <=192). Forexample, 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 thelakes. For each lake i, the number of fish expected to be caught in the initial5 minutes, denoted fi( fi >= 0 ), is known. Each 5 minutes of fishingdecreases the number of fish expected to be caught in the next 5-minuteinterval by a constant rate of di (di >= 0). If the number of fish expectedto be caught in an interval is less than or equal to di , there will be no morefish left in the lake in the next interval. To simplify the planning, Johnassumes that no one else will be fishing at the lakes to affect the number offish he expects to catch.

Write a program to help John plan hisfishing trip to maximize the number of fish expected to be caught. The numberof minutes spent at each lake must be a multiple of 5.

Input

You will be given a number of cases in theinput. Each case starts with a line containing n. This is followed by a linecontaining 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 ofn - 1 integers ti (1 <=i <=n - 1). Input is terminated by a case in whichn = 0.

Output

For each test case, print the number ofminutes spent at each lake, separated by commas, for the plan achieving themaximum number of fish expected to be caught (you should print the entire planon one line even if it exceeds 80 characters). This is followed by a linecontaining the number of fish expected.

If multiple plans exist, choose the onethat spends as long as possible at lake 1, even if no fish are expected to becaught in some intervals. If there is still a tie, choose the one that spendsas long as possible at lake 2, and so on. Insert a blank line between cases.

SampleInput

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

SampleOutput

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

Source

East Central North America 1999

2、算法分析

其实,这道题,我都没想出来,在网上搜了解题报告才知道是怎么回事。

因为我们钓鱼的次数跟钓鱼总次数无关,可以认为我们事先知道每个湖要钓的鱼数,钓够就换下一个湖,与顺序无关。

枚举终点在1到n个湖结束情况下最大的获取鱼的数量,取最大的一个作为解。

假设在m个湖结束,因为每个湖前面钓和放到后面钓是等价的,所以到达m个湖只要花一次路上的时间。那么每次都贪心选择当前m个湖中能钓到最多鱼的那个。

3、源码

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

#define N 25+10

int n,end[N],final,h,f[N],d[N],t[N];

void init()
{
	int i;
	scanf("%d",&h);
	h=h*60/5;
	for(i=1;i<=n;i++)
		scanf("%d",&f[i]);
	for(i=1;i<=n;i++)
		scanf("%d",&d[i]);
	for(i=1;i<=n-1;i++)
		scanf("%d",&t[i]);
}

void doit()
{
	int dis=0,answer,endnow[N],fnow[N],i,j,jnow,time;
	for(i=1;i<=n;i++)
	{
		answer=0;
		memset(endnow,0,sizeof(endnow));
		time=h-dis;
		if (time<=0) break;
		memcpy(fnow,f,sizeof(f));
		while (time)
		{
			jnow=1;
			for(j=1;j<=i;j++)
				if (fnow[j]>fnow[jnow])
					jnow=j;
			time--;
			answer+=fnow[jnow];
			fnow[jnow]-=d[jnow];
			if (fnow[jnow]<0) fnow[jnow]=0;
			endnow[jnow]++;
		}
		if (answer>final)
		{
			final=answer;
			memcpy(end,endnow,sizeof(endnow));
		}
		dis+=t[i];
	}
}

void outit()
{
	int i;
	if (final==0) end[1]=h;
	for(i=1;i<=n-1;i++)
		printf("%d, ",end[i]*5);
	printf("%d\n",end[n]*5);
	printf("Number of fish expected: %d\n\n",final);
}

int main()
{

	while (scanf("%d",&n),n)
	{
			final=0;
	memset(end,0,sizeof(end));
	memset(f,0,sizeof(f));
	memset(d,0,sizeof(d));
	memset(t,0,sizeof(t));
		init();
		doit();
		outit();
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值