1. 程式人生 > >BZOJ1096-[ZJOI2007]倉庫建設

BZOJ1096-[ZJOI2007]倉庫建設

return mat %d alt 優化 log logs 得到 math

BZOJ1096-[ZJOI2007]倉庫建設

  題意:

技術分享

  題解:

    斜率優化dp.為啥我做過的斜率優化題沒有一道是1A的???還有這道題並不難,就當我試一下mathjax吧.

    我們設$tot_{i}=\sum_{j=1}^ip_j$和$sum_i=\sum_{j=1}^ix_j*p_j$,

    則我們很容易得到一個dp方程$f_i=max(f_j+x_i*(tot_i-tot_j)-(sum_i-sum_j))+c_i$(自己體會下)

    化一下就變成$f_i=max(f_j+sum_j-x_i*tot_j)+x_i*tot_i-sum_i+c_i$,

    則對於$j>k$,選j比選k優的條件是$f_j+sum_j-x_i*tot_j<f_k+sum_k-x_i*tot_k$,

    然後這個式子再化一下變成$\frac{(f_j+sum_j)-(f_k+sum_k)}{tot_j-tot_k}<x_i$,

    然後隨意斜率優化一下就好了.

    不要說我沒講仔細,我並不是來寫題解的,我只是來試試mathjax的.

    (還有有沒有覺得我的公式特別小啊,我也不知道怎麽回事)

    (是不是覺得上一篇誌願者招募的題解沒用mathjax特別醜啊,反正我也懶得改成mathjax了,反正也沒多少人看)

#include<cstdio>
typedef long long ll;
const int maxn=1000000;
int
n; ll x[maxn+10],p[maxn+10],c[maxn+10],sum[maxn+10],tot[maxn+10],f[maxn+10]; int q[maxn+10],l,r; ll up_f(int k,int j){ return f[j]+sum[j]-f[k]-sum[k]; } ll down_f(int k,int j){ return tot[j]-tot[k]; } int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%lld%lld%lld",&x[i],&p[i],&c[i]);
for(int i=1;i<=n;++i){ tot[i]=tot[i-1]+p[i]; sum[i]=sum[i-1]+p[i]*x[i]; } for(int i=1;i<=n;++i){ for(;l<r&&up_f(q[l],q[l+1])<=x[i]*down_f(q[l],q[l+1]);++l); f[i]=f[q[l]]+sum[q[l]]-x[i]*tot[q[l]]+x[i]*tot[i]-sum[i]+c[i]; for(;l<r&&up_f(q[r],i)*down_f(q[r-1],q[r])<=up_f(q[r-1],q[r])*down_f(q[r],i);--r); q[++r]=i; } printf("%lld",f[n]); return 0; }

BZOJ1096-[ZJOI2007]倉庫建設