zoukankan      html  css  js  c++  java
  • [ZJOI2007]仓库建设

    link

    其实是一个需要许多次换元的$dp$,比较简单。

    我们通过层层操作以后得到式子$f[j]+s[j]=d[i] imes k[j]+s[i]-val[i]-d[i] imes k[i]+f[i]$

    然后会发现里面的横坐标$(X)$,纵坐标$(Y)$与斜率,然后发现还是维护下凸壳,然后就单调队列优化即可

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define int long long
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int N=1000001;
    int n,f[N],d[N],sum[N],val[N],k[N],s[N],c[N],p[N],X[N],Y[N],que[N],l,r;
    signed main(){
        memset(f,127/3,sizeof(f));
        f[0]=0;
        n=read();
        for(int i=1;i<=n;i++) d[i]=read(),sum[i]=sum[i-1]+d[i],c[i]=read(),val[i]=read();
        for(int i=1;i<=n;i++) k[i]=k[i-1]+c[i];
        for(int i=1;i<=n;i++) p[i]=d[i]*c[i];
        for(int i=1;i<=n;i++) s[i]=s[i-1]+p[i];
        l=1,r=1,que[1]=0,X[0]=k[0],Y[0]=f[0]+s[0];
        for(int i=1;i<=n;i++){
            while(l<r&&Y[que[l+1]]-Y[que[l]]<=(X[que[l+1]]-X[que[l]])*d[i])l++;
            f[i]=f[que[l]]+val[i]+d[i]*(k[i]-k[que[l]])-(s[i]-s[que[l]]);X[i]=k[i],Y[i]=f[i]+s[i];
            while(l<r&&(Y[que[r]]-Y[que[r-1]])*(X[i]-X[que[r]])>=(Y[i]-Y[que[r]])*(X[que[r]]-X[que[r-1]])) r--;
            que[++r]=i;
            
        }cout<<f[n];
    }
    View Code
  • 相关阅读:
    1052 Linked List Sorting (25 分)
    1051 Pop Sequence (25 分)
    1050 String Subtraction (20 分)
    1049 Counting Ones (30 分)
    1048 Find Coins (25 分)
    1047 Student List for Course (25 分)
    1046 Shortest Distance (20 分)
    1045 Favorite Color Stripe (30 分)
    1044 Shopping in Mars (25 分)
    1055 The World's Richest (25 分)
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/10111030.html
Copyright © 2011-2022 走看看