Walrus
2024-11-20 22:16:03
斜率优化好题。当笔记了。
注意到这里的矩阵是互不包含,且具有固定端点
对于这种选点问题,就考虑上一个从哪个矩形转移过来更优。
Tips:横坐标在数组存储里是行,也就是数组里的纵坐标。注意不要混淆。
故令
故朴素转移有:
整理一下:
这显然是
这里假设
整理并移项:
然后就可以用单调队列维护这个凸包,属于类板板题,时间复杂度
#include <bits/stdc++.h>
#define FASTIO ios::sync_with_stdio(0), cin.tie(nullptr), cout.tie(nullptr);
#define rep(i, j, k) for(int i = j; i <= k; ++i)
#define pre(i, j, k) for(int i = j; i >= k; --i)
#define pb push_back
#define int long long
#define inf 0x3fffffff
#define PII pair<int, int>
#define fi first
#define se second
using namespace std;
const int N = 2e6 + 5;
int n, C, L, l, r, res, h[N];
int dp[N], f[N], q[N << 1];
struct Martix {
int w, x, y;
bool operator < (const Martix &a) const {return x == a.x ? y < a.y : x < a.x;}
} a[N];
int X(int i) {//这里没有判,严谨点可以加上除数为 0 的情况
return a[i].x;
}
int Y(int i) {
return dp[i];
}
double slope(int i, int j) {
return 1.0 * (Y(j) - Y(i)) / (X(j) - X(i));
}
void insert(int i) {
while(l < r && slope(q[r - 1], q[r]) <= slope(q[r - 1], i)) --r;
q[++r] = i;
}
signed main() {
FASTIO
cin >> n;
rep(i, 1, n) cin >> a[i].x >> a[i].y >> a[i].w;
sort(a + 1, a + 1 + n);
l = 0, r = 1, q[++l] = 0;
rep(i, 1, n) {
while(l < r && slope(q[l], q[l + 1]) >= a[i].y) ++l;
dp[i] = max(dp[i], dp[q[l]] + (a[i].x - a[q[l]].x) * a[i].y - a[i].w);
res = max(res, dp[i]);
// cout << i << ' ' << q[l] << '\n';
insert(i);
}
cout << res;
return 0;
}