@ZCDHJ
2019-07-31T04:00:33.000000Z
字数 1059
阅读 438
未分类
考虑对于 的土地如果有 的土地满足 与 , 将不会对答案产生任何贡献。所以将这些土地删去。最后留下的土地序列按 排序后一定 递增, 递减。这样子每次最优d的决策一定是连续的区间,方程为 ,斜率优化即可。
#include <iostream>#include <cstdio>#include <algorithm>typedef long long LL;#define int LLconst int MAXN = 5e4;int n, tail, l, r;int dp[MAXN | 1], q[MAXN | 1];struct Land {int a, b;friend bool operator< (const Land &lhs, const Land &rhs) {return (lhs.a < rhs.a) || (lhs.a == rhs.a && lhs.b > rhs.b);}} a[MAXN | 1], s[MAXN | 1];inline int read() {register int x = 0;register char ch = getchar();while (!isdigit(ch)) ch = getchar();while (isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();}return x;}inline double slope(int x, int y) {return 1.0 * (dp[y] - dp[x]) / (s[x + 1].b - s[y + 1].b);}signed main() {n = read();for (int i = 1; i <= n; ++i) {a[i].a = read();a[i].b = read();}std::sort(a + 1, a + 1 + n);for (int i = 1; i <= n; ++i) {while (tail > 0 && s[tail].b <= a[i].b) --tail;s[++tail] = a[i];}l = 1;r = 1;for (int i = 1; i <= tail; ++i) {while (l < r && slope(q[l], q[l + 1]) <= s[i].a) ++l;int j = q[l];dp[i] = dp[j] + s[i].a * s[j + 1].b;while (l < r && slope(q[r - 1], q[r]) >= slope(q[r], i)) --r;q[++r] = i;}printf("%lld\n", dp[tail]);return 0;}
