钓鱼贪心解法

起先可以想到的贪心就是每次取所有湖中每个机会可以钓到的最多的鱼

网上说刘佳汝黑书《算法艺术与信息学竞赛》中有对这题有分析,但是黑书上没有代码,我在网上找到了对黑书中的部分题目的样例和代码,幸好里面有这题

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;

int main()
{
	int n, h;
	while (cin >> n)
	{
		if (n == 0) break;
		int d[26] = { 0 }, t[26] = { 0 }, f[26] = { 0 }, fs[26];
		cin >> h;
		h *= 12;//每一单位相当于一次机会
		int i, j;
		for (i = 0; i < n; i++)
			cin >> f[i];
		for (i = 0; i < n; i++)
			cin >> d[i];
		for (i = 1; i < n; i++)
			cin >> t[i];
		int time, k;
		int ans[26][26] = { 0 };
		memset(ans, 0, sizeof(ans));

		//贪心 核心代码块 详细分析
        //看这个二维数组,其实跟动态规划有点像?
        
		for (i = 1; i <= n; i++)//在前 i 个湖中每次寻找鱼最多的湖下钓
		{
			memcpy(fs, f, sizeof(f));//把fs重新更新回原始的f
			int flag = 0;
			h = h - t[i - 1];//前i个湖消耗在路上的时间,剩下就全是给钓鱼的时间, 
			                 //由于是从1开始的,所以之前累积的都已经减了,每次只需减去到新增的这个湖的时间                    
			time = h;
			while (time > 0 && flag != i)//每次寻找鱼最多的湖下钓直到时间用完(机会次数time=0)或所有湖中鱼钓完(没鱼了的湖的个数flag=i)
			{
				k = 0;
				for (j = 1; j < i; j++)
					if (fs[j] > fs[k]) k = j;//找到当前所有湖中(前i个湖)剩下鱼最多的湖
				ans[i][0] += fs[k];//ans[i][0]是总结果
				ans[i][k + 1]++;//每个这时候湖从1到i编号(不是从0开始),表示前i个湖的每个湖使用的钓鱼的次数(到时候乘以5就是时间)
				time--;
				if (fs[k] > 0)
				{
					fs[k] -= d[k];
					if (fs[k] < 0) fs[k] = 0;
				}
				flag = 0;
				for (j = 0; j < i; j++)
					if (fs[j] <= 0) flag++;
			}
			//将剩余时间加到一个湖中用时
			ans[i][1] += time;
		}


		k = 1;
		for (j = 2; j <= n; j++)
			if (ans[j][0] > ans[k][0]) k = j;
		for (j = 1; j <= n; j++)
		{
			cout << ans[k][j] * 5;
			if (j != n) cout << ", ";
		}
		cout << endl;
		cout << "Number of fish expected: " << ans[k][0] << endl;
		cout << endl;
	}
	return 0;
}

感谢黑书的解析哦!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值