1. 程式人生 > >【筆記】斜率優化dp

【筆記】斜率優化dp

BZOJ 1096 倉庫建設

/* LittleFall : Hello! */
#include <bits/stdc++.h>
typedef long long ll;
using namespace std; inline int read();
const int M = 1000016, MOD = 1000000007;

ll X[M], P[M], C[M], sp[M], sxp[M];
ll dp[M];
inline double slope(int k, int j)
{
	return double(dp[j]-dp[k]+sxp[j]-sxp[k])/double(sp[j]-sp[k]
); } int q[M]; //雙端佇列 int main(void) { #ifdef _LITTLEFALL_ freopen("in.txt","r",stdin); #endif int n = read(), l=0, r=0; for(int i=1;i<=n;++i) { X[i] = read(), P[i] = read(), C[i] = read(); sp[i] = sp[i-1] + P[i]; sxp[i] = sxp[i-1] + P[i]*X[i]; } for(int i=1,t;i<=n;++i) { while
(l<r && slope(q[l],q[l+1])<X[i]) l++; //pop_front t = q[l]; dp[i] = C[i] + dp[t] - (sxp[i]-sxp[t]) + X[i]*(sp[i]-sp[t]); while(l<r && slope(q[r-1],q[r])>slope(q[r],i)) r--; //pop_back q[++r] = i; //push_back } cout << dp[n] << endl; return 0; } inline
int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; }