_bzoj1096 [ZJOI2007]仓库建设【斜率优化dp】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1096
又是一道经典斜率优化。
#include <cstdio> const int maxn = 1000005; int n, c[maxn], head, tail, x[maxn]; long long sp[maxn], sxp[maxn], f[maxn]; char ch; struct point { long long x, y; int id; } que[maxn], tem; inline void readint(int & rt) { while ((ch = getchar()) < 48); rt = ch - 48; while ((ch = getchar()) > 47) { rt = rt * 10 + ch - 48; } } inline void readll(long long & rt) { while ((ch = getchar()) < 48); rt = ch - 48; while ((ch = getchar()) > 47) { rt = rt * 10 + ch - 48; } } int main(void) { //freopen("in.txt", "r", stdin); readint(n); for (int i = 1; i <= n; ++i) { readint(x[i]); readll(sp[i]); readint(c[i]); sxp[i] = (long long)x[i] * sp[i] + sxp[i - 1]; sp[i] += sp[i - 1]; } que[tail++] = (point){0, 0, 0}; int j; for (int i = 1; i <= n; ++i) { while (tail - head > 1 && que[head].y - que[head + 1].y > x[i] * (que[head].x - que[head + 1].x)) { ++head; } j = que[head].id; f[i] = f[j] + (long long)x[i] * (sp[i] - sp[j]) - (sxp[i] - sxp[j]) + (long long)c[i]; tem = (point){sp[i], f[i] + sxp[i], i}; while (tail - head > 1 && (tem.y - que[tail - 1].y) * (que[tail - 1].x - que[tail - 2].x) < (que[tail - 1].y - que[tail - 2].y) * (tem.x - que[tail - 1].x)) { --tail; } que[tail++] = tem; } printf("%lld\n", f[n]); return 0; }