题目链接
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=dpi−1,j−ti−1
钓鱼
(
(
(
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,dpi−1,j−ti−k+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;
}