[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1096
[算法]
斜率优化
时间复杂度 : O(N)
[代码]
#include<bits/stdc++.h> using namespace std; #define N 1000010 typedef long long ll; typedef long double ld; typedef unsigned long long ull; int n , l , r; ll ans , totsum; int q[N]; ll a[N] , cst[N] , pref[N] , suf[N] , f[N] , dis[N] , X[N] , Y[N]; template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); } template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } int main() { read(n); for (int i = 1; i <= n; i++) { read(dis[i]); read(a[i]); read(cst[i]); } totsum = cst[n]; for (int i = 1; i <= n; i++) { suf[i] = dis[n] - dis[i]; pref[i] = pref[i - 1] + a[i]; totsum += suf[i] * a[i]; } // f0 = totsum // fi = min{ fj - (prefi - prefj) * sufi + csti } // fi = min{ fj - prefi * sufi + prefj * sufi + csti } // fj = Yj , prefj = Xj // Yj = fi + prefi * sufi - Xj * sufi - csti} // Yj = -sufi * Xj + fi + prefi * sufi - csti X[0] = 0; f[0] = Y[0] = totsum; q[l = r = 1] = 0; ll ans = totsum; for (int i = 1; i <= n; i++) { // (Yql+1 - Yql) / (Xql+1 - Xql) <= k while (l < r && Y[q[l + 1]] - Y[q[l]] <= -suf[i] * (X[q[l + 1]] - X[q[l]])) ++l; f[i] = f[q[l]] - (pref[i] - pref[q[l]]) * suf[i] + cst[i]; X[i] = pref[i]; Y[i] = f[i]; chkmin(ans , f[i]); // (Yi - Yqr) / (Xi - Xqr) <= (Yqr - Yqr-1) / (Xqr - Xqr-1) while (l < r && (Y[i] - Y[q[r]]) * (X[q[r]] - X[q[r - 1]]) <= (Y[q[r]] - Y[q[r - 1]]) * (X[i] - X[q[r]])) --r; q[++r] = i; } printf("%lld " , ans); return 0; }