bzoj 1835 ZJOI2010 基站選址

2021-08-14 22:27:27 字數 2204 閱讀 3505

有n個村莊坐落在一條直線上,第i(i>1)個村莊距離第1個村莊的距離為di。需要在這些村莊中建立不超過k個通訊基站,在第i個村莊建立基站的費用為ci。如果在距離第i個村莊不超過si的範圍內建立了乙個通訊基站,那麼就成它被覆蓋了。如果第i個村莊沒有被覆蓋,則需要向他們補償,費用為wi。現在的問題是,選擇基站的位置,使得總費用最小。

輸入資料 (base.in) 輸入檔案的第一行包含兩個整數n,k,含義如上所述。 第二行包含n-1個整數,分別表示d2,d3,…,dn,這n-1個數是遞增的。 第三行包含n個整數,表示c1,c2,…cn。 第四行包含n個整數,表示s1,s2,…,sn。第五行包含n個整數,表示w1,w2,…,wn。

這道題是dp,相信這是顯而易見的。但不是裸dp,磨了我好久,關鍵是這題是線段樹優化dp。dp方程為f[j][i]=f[j-1][k]+cost[k][i](j-1<= k<= i-1),其中cost[k][i]意為從k到i之間要補償的村莊的總費用,然而我們可以把第一維提前,變成f[i]=f[k]+cost[k][i]。

先用二分求出每個點的st(如果建立基站最前的可以覆蓋到它的點)和ed(如果建立基站最後的可以覆蓋到它的點),然後我們發現如果我們現在列舉到i,並且ed[k]=i,那麼在i+1時,1~st[k]-1建基站就覆蓋不到k(i+1也覆蓋不到k),所以cost[j][i+1]+=w[k](1<= j<= st[k]-1),而我們要維護f[k][j]+cost[k][i](j<= k<= i-1,i為當前列舉到的點),對於這種區間詢問與修改,我們便想到了線段樹。

這便是大體思路,接下來就要看實現能力了。(其實可以不用二分查詢st和ed,stl**好,但本蒟蒻不會)

#include

#include

#include

#include

#include

using namespace std;

int n,m;

int d[20005],c[20005],s[20005],w[20005];

int f[20005],st[20005];

struct node

a[40010];int len,last[40010];

void ins(int

x,int

y)struct trnode

tr[40010];int trlen;

void bt(int l,int r)

}void change(int now,int l,int r,int k)

intlc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;

if(tr[now].add!=0)

if(midelse

if(mid>=r)change(lc,l,r,k);

else change(lc,l,mid,k),change(rc,mid+1,r,k);

tr[now].c=min(tr[lc].c,tr[rc].c);

}int getmin(int now,int l,int r)

if(midreturn getmin(rc,l,r);

else

if(mid>=r)return getmin(lc,l,r);

else

return min(getmin(lc,l,mid),getmin(rc,mid+1,r));

}int check1(int

x) else l=mid+1;

}return ans;

}int check2(int

x) else r=mid-1;

}return ans;

}int main()

n++;//新增乙個節點,d灰常大,使得前面的節點覆蓋不它,

而w也很大,可c為0,使得它一定被作為基站,這對結果不影響,

還可方便記錄結果,直接為f[n]

d[n]=w[n]=0x3f3f3f3f;c[n]=s[n]=0;

ins(n,n);st[n]=n;

int he=0;

for(int i=1;i<=n;i++)

}ans=f[n];

for(int j=2;j<=m;j++)

}ans=min(ans,f[n]);

}printf("%d\n",ans);

return

0;}

BZOJ1835 ZJOI2010 基站選址

原題傳送門 有n個村莊坐落在一條直線上,第i i 1 個村莊距離第1個村莊的距離為di。需要在這些村莊中建立不超過k個通訊基站,在第i個村莊建立基站的費用為ci。如果在距離第i個村莊不超過si的範圍內建立了乙個通訊基站,那麼就成它被覆蓋了。如果第i個村莊沒有被覆蓋,則需要向他們補償,費用為wi。現在...

bzoj1835 線段樹優化dp)

神題啊,好吧,應該是因為我太弱了。設f i k 表示到第i個村莊,第i個村莊一定會建基站,已經建了k個基站的最小費用.f i k min c i 注意本題線段樹維護的是當我們列舉i的時候,線段樹來維護f j k 1 cost j i 就是之前的值和中間的值,整體維護dp方程中的東西。同時在列舉i增加...

BZOJ1003 ZJOI 物流運輸

物流公司要把一批貨物從碼頭a運到碼頭b。由於貨物量比較大,需要n天才能運完。貨物運輸過程中一般要轉停好幾個碼頭。物流公司通常會設計一條固定的運輸路線,以便對整個運輸過程實施嚴格的管理和跟蹤。由於各種因素的存在,有的時候某個碼頭會無法裝卸貨物。這時候就必須修改運輸路線,讓貨物能夠按時到達目的地。但是修...