鱼塘钓鱼(多路归并)

文章讨论了一个问题,如何在有限的时间内,从一系列鱼塘出发,设计一个最优钓鱼方案,以获取最大的鱼总数量。通过考虑鱼的生长和减少速度,以及鱼塘间的移动时间,提出算法来计算在截止时间T内的最大捕鱼量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有 N
个鱼塘排成一排,每个鱼塘中有一定数量的鱼,例如:N=5
时,如下表:

鱼塘编号12345
第1分钟能钓到的鱼的数量 (1…1000)101420169
每钓鱼1分钟钓鱼数的减少量(1…100)24653
当前鱼塘到下一个相邻鱼塘需要的时间(单位:分钟)3544

即:在第 111 个鱼塘中钓鱼第 111 分钟内可钓到 101010 条鱼,第 222 分钟内只能钓到 888 条鱼,……,第 555 分钟以后再也钓不到鱼了。

从第 111 个鱼塘到第 222 个鱼塘需要 333 分钟,从第 222 个鱼塘到第 333 个鱼塘需要 555 分钟,……

给出一个截止时间 TTT,设计一个钓鱼方案,从第 111 个鱼塘出发,希望能钓到最多的鱼。

假设能钓到鱼的数量仅和已钓鱼的次数有关,且每次钓鱼的时间都是整数分钟。

输入格式

555 行,分别表示:

111 行为 NNN

222 行为第 111 分钟各个鱼塘能钓到的鱼的数量,每个数据之间用一空格隔开;

333 行为每过 111 分钟各个鱼塘钓鱼数的减少量,每个数据之间用一空格隔开;

444 行为当前鱼塘到下一个相邻鱼塘需要的时间;

555 行为截止时间 TTT

输出格式

一个整数(不超过231−1231−12311),表示你的方案能钓到的最多的鱼。

数据范围

1≤N≤1001≤N≤1001N100,
1≤T≤10001≤T≤10001T1000

输入样例:

5
10 14 20 16 9
2 4 6 5 3
3 5 4 4
14

输出样例:

76
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 110;

int a[N], d[N], l[N], spend[N];

int get(int k) {                                //第i分钟在第k个鱼塘钓到鱼的数量
	return max(0, a[k] - d[k] * spend[k]);
}

int work(int n, int T) {                        //只走前n个鱼塘,且时间为T的最大收益
	int res = 0;
	memset(spend, 0, sizeof spend);
	for (int i = 0; i < T; i ++ ) {             //按分钟遍历
		int t = 1;                              //t表示第i分钟第t的鱼塘的鱼最多,初始为1号鱼塘
		for (int j = 1; j <= n; j ++ )          //第i分钟在前n个鱼塘的最大收益
			if (get(j) > get(t))
				t = j;

		res += get(t);
		spend[t] ++ ;                           //在t号鱼塘逗留时间+1
	}
	return res;
}

int main() {
	int n, T;                                   //n个鱼塘,截止时间为T
	cin >> n;
	for (int i = 1; i <= n; i ++ ) cin >> a[i]; //各鱼塘第一分钟产鱼量
	for (int i = 1; i <= n; i ++ ) cin >> d[i]; //各鱼塘每一分钟减鱼量
	for (int i = 2; i <= n; i ++ ) {            //从第一个鱼塘到第i个鱼塘之间的距离
		cin >> l[i];
		l[i] += l[i - 1];                       //因为这步求前缀和,所以前面下标i要从1开始
	}
	cin >> T;

	int res = 0;
	for (int i = 1; i <= n; i ++ )              //从第一个鱼塘出发,遍历n个鱼塘
		res = max(res, work(i, T - l[i]));      //只去前i个鱼塘的最大收益,这里已经减去路上所用时间

	cout << res << endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值