「题解」洛谷 P1717 钓鱼
题目
简化题意
有 \(n\) 个池塘排在一条直线上,起始在 \(1\) 号池塘,在池塘之间移动需要花费时间,在每个池塘单位时间钓到的鱼不同并且每吊一个单位时间的鱼这个量会减少。
思路
可以发现不可能从编号大的池塘走到编号小的池塘,因为往回走纯粹浪费时间不如一开始先不去编号大的池塘,先在编号小的池塘钓,然后再去编号大的池塘。
那么我们可以枚举最后在哪个池塘,然后贪心的去做,将枚举的 \(i\) 号池塘及之前池塘单位时间能钓到的鱼放入大根堆中每次取最大值并且修改一下这个值即可。
Code
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#define MAXN 25
int max(int a, int b) { return a > b ? a : b; }
typedef std::pair<int, int> pii;
std::priority_queue<pii> q;
int n, h, ans = 0;
int f[MAXN], d[MAXN], t[MAXN];
int main() {
scanf("%d %d", &n, &h), h = h * 12;
for (int i = 1; i <= n; ++i) scanf("%d", &f[i]);
for (int i = 1; i <= n; ++i) scanf("%d", &d[i]);
for (int i = 1; i < n; ++i) scanf("%d", &t[i]);
for (int i = 1; i <= n; ++i) {
h -= t[i - 1];
int temph = h, tot = 0;
for (int j = 1; j <= i; ++j) {
q.push(std::make_pair(f[j], j));
}
while(temph > 0 && !q.empty()) {
pii now = q.top(); q.pop();
tot += now.first;
now.first -= d[now.second];
if (now.first > 0) q.push(now);
--temph;
}
ans = max(ans, tot);
while(!q.empty()) q.pop();
}
std::cout << ans << '\n';
return 0;
}