BZOJ1096 ZJOI2007 倉庫建設


Description

L公司有N個工廠,由高到底分佈在一座山上,工廠1在山頂,工廠N在山腳。由於這座山處於高原內陸地區(乾燥少雨),L公司一般把產品直接堆放在露天,以節省費用。突然有一天,L公司的總裁L先生接到氣象部門的電話,被告知三天之後將有一場暴雨,於是L先生決定緊急在某些工廠建立一些倉庫以免產品被淋壞。

由於地形的不同,在不同工廠建立倉庫的費用可能是不同的。第i個工廠目前已有成品Pi件,在第i個工廠位置建立倉庫的費用是Ci。對於沒有建立倉庫的工廠,其產品應被運往其他的倉庫進行儲藏,而由於L公司產品的對外銷售處設置在山腳的工廠N,故產品只能往山下運(即只能運往編號更大的工廠的倉庫),當然運送產品也是需要費用的,假設一件產品運送1個單位距離的費用是1。假設建立的倉庫容量都都是足夠大的,可以容下所有的產品。

在每一行,你都將得到以下數據:
1.工廠i距離工廠1的距離Xi(其中X1=0)
2.工廠i目前已有成品數量Pi
3.在工廠i建立倉庫的費用Ci

請你幫助L公司尋找一個倉庫建設的方案,使得總的費用(建造費用+運輸費用)最小。

Sample Input & Output

3
0 5 10
5 3 100
9 6 10

32


小P的牧場

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 1000005
int X[M],A[M],B[M];
long long sum1[M],sum2[M],dp[M];
int deq[M],L=0,R=-1,n;
long long calc(int L,int R){return dp[L]+A[R]+(sum1[R]-sum1[L])*X[R]-(sum2[R]-sum2[L]);}
long long up(int L,int R){return dp[R]-dp[L]+sum2[R]-sum2[L];}
long long down(int L,int R){return sum1[R]-sum1[L];}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d %d %d",&X[i],&B[i],&A[i]);
    for(int j=1;j<=n;j++){
        sum1[j]=sum1[j-1]+B[j];
        sum2[j]=sum2[j-1]+1LL*B[j]*X[j];
    }
    deq[++R]=0;
    for(int i=1;i<=n;i++){
        while(L<R&&up(deq[L],deq[L+1])<X[i]*down(deq[L],deq[L+1]))++L;
        dp[i]=calc(deq[L],i);
        while(L<R&&up(deq[R-1],deq[R])*down(deq[R],i)>=down(deq[R-1],deq[R])*up(deq[R],i))--R;
        deq[++R]=i;
    }
    printf("%lld\n",dp[n]);
    return 0;
} 
發佈了48 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章