poj_1042

题目链接:http://poj.org/problem?id=1042

题目大意:有n个池塘,编号从1-n,有个人从1号塘开始钓鱼,每个池塘刚开始的5分钟内能钓上fi[i]条鱼,之后每过5分钟,能钓上的鱼就减少di[i]条,如果一个人要在某个池塘钓鱼,那么他至少得花费5分钟,再呆下去就是10分钟,,以此类推,除了钓鱼时间外,还有从第i-1号池塘到i号池塘的时间是ti[i-1]*5分钟。人要到达某个池塘,一定得按顺序走(即i,i+1,i+2...)。某个人一共有h*60分钟,问你在这有限时间内,最多能钓到几条鱼,并输出在每个池塘花费的时间。

思路:贪心+枚举

我们知道一共有n个池塘,并且人只能从上一个池塘走到下一个池塘,所以我们枚举人走到最后的池塘i的编号,并用总时间减去从1-i用在走路上面的时间,这样子我们得到的最后的时间就是用在钓鱼上面的。

得到总时间后,我们就在前1-i个池塘中进行贪心,每5分钟选择一个能够钓上来鱼最多的池塘,此时人的转移可以看做是瞬间的,但其实从宏观上来讲,人的转移是有序的,只不过为了得到最多的鱼,我们将人假装看做是瞬间的,实际上做选择的时候就是按顺序来做的。每次选择那个池塘后,我们将该池塘的可钓鱼数-di[i],时间+5,。。。直到把所有时间都花费完。

#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<time.h>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
#include<set>
#include<map>
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define sfs(a) scanf("%s",a)
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfI(a) printf("%I64d\n",a)
#define pfs(a) printf("%s\n",a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,c)scanf("%d%d%d",&a,&b,&c)
#define for1(i,a,b) for(int i=(a);i<b;i++)
#define for2(i,a,b) for(int i=(a);i<=b;i++)
#define for3(i,a,b)for(int i=(b);i>=a;i--)
#define MEM1(a) memset(a,0,sizeof(a))
#define MEM2(a) memset(a,-1,sizeof(a))
const double PI=acos(-1.0);
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
using namespace std;
#define ll  __int64
#define N 110
int n,m;
int h;
int fi[N];
int di[N];
int ti[N];
int p[N];
struct Node{
	int tm[N];
	int mmax;
	void clear(){
		memset(tm,0,sizeof tm);
		mmax=0;
	}
}a[N];
int getMax(int x){	//get the id of the pond which we can get the most fish
	int mmax=-1;
	int flag;
	for(int i=1;i<=x;i++){
		if(p[i]>mmax){
			mmax=p[i];
			flag=i;
		}
	}
	return flag;
}
void getResult(){
	int total = h*60;		//total time
	for(int i=0;i<=n;i++)
		a[i].clear();
	for(int i=1;i<=n;i++){
		int tmp = total;
		for(int j=1;j<=i;j++){
			p[j] = fi[j];
			if(j<i)
				tmp -= (ti[j])*5;		//the time rested to fish(total time - walking time)
		}
		int s=0;
		while(s<tmp){
			int id = getMax(i);						//for one time,we choose a place which can fish the most fish
			a[i].mmax += p[id];			//a[i].mmax denotes the remotest place we can reach is i and the most fish we can have is a[i].mmax
			a[i].tm[id] += 5;						//at place id we spend 5 minutes
			p[id] -= di[id];						//place id decrease fish by di[id]
			if(p[id]<0) p[id]=0;
			s += 5;
		}
	}
	for(int i=1;i<=n;i++)
		p[i] = a[i].mmax;			//find the most fish we can get
	int flag = getMax(n);
	printf("%d",a[flag].tm[1]);							//print the time we spend on every pond
	for(int i=2;i<=n;i++)
		printf(", %d",a[flag].tm[i]);
	printf("\n");
	printf("Number of fish expected: %d\n",a[flag].mmax);
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
#endif
//	int t;
	int flag=0;
	while(sf(n)!=EOF && n){
		if(flag)printf("\n");
		sf(h);
		for(int i=1;i<=n;i++)
			sf(fi[i]);
		for(int i=1;i<=n;i++)
			sf(di[i]);
		for(int i=1;i<n;i++)
			sf(ti[i]);
		getResult();
		flag=1;
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值