CodeForces 1083 E The Fair Nut and Rectangles 斜率优化DP
题意:有n个矩形,然后你可以选择k个矩形,选择一个矩形需要支付代价 ai, 问 总面积- 总支付代价 最大能是多少, 保证没有矩形套矩形。
题解:
sort 一下 只有 x 会递增 y 递减
然后 f[i] = f[j] + (x[i]-x[j])*y[i] - a[i]
f[j] = f[i] - x[i] * y[i] + x[j] * y[i] + a[i]
即 y = f[j], x = x[j], k = y[i], b = f[i] - x[i] * y[i] + a[i]
我们需要维护 f[i] 尽可能大, 所以我们维护一个上突壳就好了。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e6 + 100; struct Node{ int x, y; LL a; bool operator < (const Node & z) const{ return x < z.x; } }A[N]; LL f[N]; int q[N]; int main(){ int n; scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d%d%lld", &A[i].x, &A[i].y, &A[i].a); sort(A+1, A+1+n); int L = 1, R = 1; for(int i = 1; i <= n; ++i){ while(L < R && f[q[L+1]]-f[q[L]]>= 1ll*A[i].y * ((A[q[L+1]].x - A[q[L]].x))) ++L; f[i] = f[q[L]] + (1ll*A[i].x-A[q[L]].x)*A[i].y - A[i].a; while(L < R && ((long double)f[q[R]]-f[q[R-1]]) * (A[i].x - A[q[R]].x) <= ((long double)f[i]-f[q[R]]) * ((A[q[R]].x - A[q[R-1]].x))) --R; q[++R] = i; } LL ans = 0; for(int i = 1; i <= n; ++i) ans = max(ans, f[i]); cout << ans << endl; return 0; }