洛谷2120 [ZJOI2007]倉庫建設(斜率優化dp)
阿新 • • 發佈:2018-12-28
感覺和鋸木廠那個題很類似的。
其實這個題還那個題唯一的區別就是\(dp\)轉移式子中的\(f\)變成了\(g\)
qwq不想多說了
直接看我的前一篇題解吧qwq
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #include<map> #include<set> #define mk make_pair #define ll long long #define int long long using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();} while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } const int maxn = 1e6+1e2; int n,m; int w[maxn],d[maxn]; int f[maxn]; int dis[maxn],val[maxn],sum[maxn]; int sw[maxn]; struct Point{ int x,y,num; }; Point q[maxn]; int chacheng(Point x,Point y) { return x.x*y.y-x.y*y.x; } bool count(Point i,Point j,Point k) { Point x,y; x.x=k.x-i.x; x.y=k.y-i.y; y.x=k.x-j.x; y.y=k.y-j.y; if (chacheng(x,y)<=0) return true; return false; int head=1,tail=0; void push(Point x) { while (tail>=head+1 && count(q[tail-1],q[tail],x)) tail--; q[++tail]=x; } void pop(int lim) { while(tail>=head+1 && q[head+1].y-q[head].y < lim * (q[head+1].x-q[head].x)) head++; } int g[maxn]; int ymh[maxn]; signed main() { n=read(); for (int i=1;i<=n;i++) d[i]=read(),w[i]=read(),ymh[i]=read(); for (int i=1;i<=n;i++) dis[i]=d[n]-d[i]; for (int i=1;i<=n;i++) sw[i]=sw[i-1]+w[i]; for (int i=1;i<=n;i++) val[i]=w[i]*dis[i]; for (int i=1;i<=n;i++) sum[i]=sum[i-1]+val[i]; g[0]=sum[n]; push((Point){0,sum[n],0}); for (int i=1;i<=n;i++) { pop((-1)*dis[i]); int now = q[head].num; g[i]=min(g[now]-(sw[i]-sw[now])*dis[i]+ymh[i],g[i-1]); push((Point){sw[i],g[i],i}); } cout<<g[n]+ymh[n]; return 0; }