一本通 1.1 练习 5【钓鱼】

题目linkhttps://loj.ac/problem/10009

首先对于每一个鱼池,必须经过前面的鱼池才可以在当前鱼池钓鱼,因此可以先枚举终点,即最后在哪个鱼池结束钓鱼;然后再判断在当前鱼池钓几次鱼,选择最优的情况。$O(1e5$ $log$ $1e5)$

详见代码。并不会很有逻辑性的证明。

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 using namespace std;
 4 int n, h, f[110], d[110], t[110], ans, tot; //tot是从1到当前时间的最多得分总和,可以累加 
 5 priority_queue < int, vector < int >, greater < int > > pru; //小根堆堆顶存得分最少的方案 
 6 int main()
 7 {
 8     scanf("%d %d", &n, &h); h *= 12; //由于题目中是5min为一个单位的,所以小时变分钟直接 * 60再 / 5及 * 12就行了,以下说的1单位时间与题目中的5单位时间相同 
 9     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]);
10     for(int i = 1; i <= n && h > 0; h -= t[i], ++i)
11     {
12         for(int o = 1; o <= 1000 && f[i] > 0; ++o) pru.push(f[i]), tot += f[i], f[i] -= d[i]; //每放入一个选了的方案,即钓了一次鱼,花费1单位时间,因为这个f[i]可能非常大(没给范围),d可能非常小,所以整个o判断一下次数,但是我并不知道o取多少能恰好不出问题
13         while(pru.size() > h) tot -= pru.top(), pru.pop(); //这里pru.size和h都是单位时间,所以条件成立 
14         ans = max(ans, tot);
15     }
16     printf("%d", ans);
17     return 0;
18 } 
原文地址:https://www.cnblogs.com/qqq1112/p/13908063.html