斜率优化dp
模板题:loj10185
#include<cstdio> #include<iostream> using namespace std; const int maxn = 300010; inline int qread(){ register int ch = getchar(), x = 0; while(ch < 48 || ch > 57) ch = getchar(); while(ch > 47 && ch < 58) x = (x << 3) + (x << 1) + ch - 48, ch = getchar(); return x; } int T[maxn], C[maxn], sumT[maxn], sumC[maxn], f[maxn]; int n, S; int qu[maxn]; int head = 1, tail = 1; int main(void){ n = qread(); S = qread(); for(int i = 1; i <= n; ++i) T[i] = qread(), C[i] = qread(); for(int i = 1; i <= n; ++i) sumT[i] = sumT[i - 1] + T[i], sumC[i] = sumC[i - 1] + C[i]; for(int i = 1; i <= n; ++i){ while(head < tail && f[qu[head + 1]] - f[qu[head]] <= (S + sumT[i]) * (sumC[qu[head + 1]] - sumC[qu[head]])) ++head; f[i] = f[qu[head] + sumT[i] * (sumC[i] - sumC[qu[head]) + S * (sumC[n] - sumC[qu[head]); while(head < tail && (f[qu[tail]] - f[qu[tail - 1]]) * (sumC[i] - sumC[qu[tail]]) >= (f[i] - f[qu[tail]]) * (sumC[qu[tail]] - sumC[qu[tail - 1]])) --tail; qu[++tail] = i; } printf("%d\n", f[n]); }