洛谷P1717 钓鱼(多重背包)

题目链接

https://www.luogu.com.cn/problem/P1717

思路

在每一个地方都可以钓任意时间的鱼,但当钓鱼的时间长了之后能钓的鱼的数量就会变成负数, n n n最大为 25 25 25 h h h最大为 16 × 60 16 \times 60 16×60,因此这是一个多重背包问题。
d p i , j dp_{i,j} dpi,j表示前 i i i个池塘,时间限制为 j j j时最多能钓多少鱼,则状态转移方程为:
不钓鱼: d p i , j = d p i − 1 , j − t i − 1 dp_{i,j} = dp_{i-1,j-t_{i-1}} dpi,j=dpi1,jti1
钓鱼 ( ( ( t m p tmp tmp记录在第 i i i个池塘能钓的鱼少了多少 ) ) )
d p i , j = m a x ( d p i , j , d p i − 1 , j − t i − k + f i ∗ ( k / 5 ) + t m p ) dp_{i,j} = max(dp_{i,j},dp_{i-1,j-t_{i}-k}+f_{i}*(k/5)+tmp) dpi,j=max(dpi,j,dpi1,jtik+fi(k/5)+tmp)

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 30 + 5, M = 1e3 + 5;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n, h;
int f[N], d[N], t[N], dp[N][M];
void solve()
{
	cin >> n >> h;
	h *= 60;
	for (int i = 1; i <= n; i++)
	{
		cin >> f[i];
	}
	for (int i = 1; i <= n; i++)
	{
		cin >> d[i];
	}
	for (int i = 1; i < n; i++)
	{
		cin >> t[i];
		t[i] *= 5;
	}
	for (int i = 1; i <= n; i++)
		for (int j = 0; j <= h; j++)
			dp[i][j] = -inf;

	dp[1][0] = 0;
	for (int i = 1; i <= n; i++ )
	{
		for (int j = h; j >= t[i - 1]; j--)
		{
			dp[i][j] = dp[i - 1][j - t[i - 1]];
			int tmp = 0;
			for (int k = 5; k <= j; k += 5)
			{
				if (j - t[i - 1] - k < 0) break;
				dp[i][j] = max(dp[i][j], dp[i - 1][j - t[i - 1] - k] + f[i] * (k / 5) - tmp);
				tmp += (k / 5) * d[i];
			}
		}
	}

	int ans = 0;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 0; j <= h; j++)
		{
			ans = max(ans, dp[i][j]);
		}
	}
	cout << ans << endl;

}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int test = 1;
	// cin >> test;
	for (int i = 1; i <= test; i++)
	{
		solve();
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值