POJ 1042 Gone Fishing

3 篇文章 0 订阅
2 篇文章 0 订阅

POJ 1042 Gone Fishing


算法分析:分析下来,其实是一道枚举+贪心问题,首先枚举钓鱼者可能到达的最大水池,然后总时间减去到达最大水池的时间,接着就可以用贪心法不断地寻找当前拥有最多鱼的水池。值得注意的是使用贪心法有一个好处就是非常容易满足输出要求的条件,而这道题似乎有另外一种解法动态规划则好像需要特殊处理才能够满足这个条件(不过我也没有过多注意DP算法)。


算法实现:调试了好久WA了好几次,第一次是因为忘了每次枚举的时候初始化最初池中的鱼数量;初次WA是初始化最多鱼数量的时候初始化成了0,但其实需要初始化为负数,否则没法输出池子没有鱼的解决方案;第三次……没看清楚输出格式忘了输出两个回车。


代码实现:

#include <iostream>
using namespace std;

int h;	//hours
int n;	//lakes
int fi[26];	//fishes at first
int cfi[26];
int di[26];	//decrease
int ti[25]; //time between i and i+1
int time; //time cost in traveling
int stay[26]; //time at each lakes
int maxstay[26]; 
int fish;	//fishes
int maxium;

void Fishing(int nn)
{
	int tmp=1;	//记录当前准备钓鱼湖
	int tmpfish=0;	//记录所有湖中有最多鱼的
	for (int i=1; i<=nn; i++)
		if (fi[i]>tmpfish)
		{
			tmp=i;
			tmpfish=fi[i];
		}
	stay[tmp]++;
	fish+=fi[tmp];
	fi[tmp]-=di[tmp];
	if (fi[tmp]<0)
		fi[tmp]=0;
	return;
}

int main()
{

	while (cin>>n && (n!=0))
	{
		//初始化
		ti[0]=0;
		maxium=-1;	//初始化为负数才可以

		//输入
		cin>>h;
		h=h*12;
		for (int i=1; i<=n; i++)
		{
			cin>>cfi[i];
		}
		for (int i=1; i<=n; i++)
		{
			cin>>di[i];
		}
		for (int i=1; i<=n-1; i++)
		{
			cin>>ti[i];
		}

		//单个枚举
		for (int i=1; i<=n; i++)
		{
			for (int j=1; j<=n; j++)
			{
				fi[j]=cfi[j];
			}
			for (int j=1; j<=n; j++)
			{
				stay[j]=0;
			}

			fish=0;
			time=0;
			for (int j=1; j<=i; j++)
			{
				time+=ti[j-1];
			}
			if (time>=h)
				break;
			time=h-time;

			while (time--)
			{
				Fishing(i);
			}
			if (fish>maxium)
			{
				for (int k=1; k<=n; k++)
				{
					maxstay[k]=stay[k];
				}
				maxium=fish;
			}
		}

		//输出
		for (int i=1; i<=n; i++)
		{
			if (i==1)
			{
				cout<<maxstay[i]*5;
			}
			else
			{
				cout<<", "<<maxstay[i]*5;
			}
//			printf("%d, ",maxstay[i]*5);  
		}
		cout<<endl;
		cout<<"Number of fish expected: "<<maxium<<endl;
		cout<<endl;
//		printf("%d\nNumber of fish expected: %d\n\n",maxstay[n]*5,maxium);  

	}
	return 0;
}

参考资料:这道题是我在看算法艺术与信息学竞赛的时候的练手题,题目为1.2.2贪心法的例题一。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值