有n個村莊坐落在一條直線上,第i(i>1)個村莊距離第1個村莊的距離為di。需要在這些村莊中建立不超過k個通訊基站,在第i個村莊建立基站的費用為ci。如果在距離第i個村莊不超過si的範圍內建立了乙個通訊基站,那麼就成它被覆蓋了。如果第i個村莊沒有被覆蓋,則需要向他們補償,費用為wi。現在的問題是,選擇基站的位置,使得總費用最小。
輸入檔案的第一行包含兩個整數n,k,含義如上所述。
第二行包含n
-1個整數,分別表示d2,d3,…,dn ,這n-1個數是遞增的。
第三行包含n個整數,表示c1,c2,…cn。
第四行包含n個整數,表示s1,s2,…,sn。
第五行包含n個整數,表示w1,w2,…,wn。
輸出檔案中僅包含乙個整數,表示最小的總費用。
1 2
2 3 2
1 1 0
10 20 30
4
40%的資料中,n
<=500;
100%的資料中,k
<=n,k
<=100,n
<=20,000,di
<=1000000000,ci
<=10000,si
<=1000000000,wi
<=10000。
solution
先列出dp式
f[i][j]表示當前建到i(i必建),已經建了j個的最小代價
f[i][j]=f[k][j-1]+cost(k+1,i-1)+c[i];
效率o(n^3)
因為j只和j-1有關,我們可以先列舉j,對於每乙個j,考慮優化cost(k+1,i-1):
令l[i]為最左的能覆蓋i的基站的位置,r[i]同理
用線段樹存1~i-1 f[k][j-1]+cost(k+1,i-1 ) 的值
處理完i,將要加入i+1時對於r[x]=i的點顯然無法被從右邊覆蓋,那麼將1~l[x]-1加上w[x],
也就是如果f[i+1]由f[k]轉移來,且**段樹維護區間加,單點查
效率o(nlogn)
#include#include#include#include#include#include#include#include#include#define maxn 200005
#define inf 900000000
using namespace std;
int n,k,dp[maxn],d[maxn],c[maxn],s[maxn],w[maxn],lm[maxn],rm[maxn];
int x,tot,head[maxn];
struct nodee[maxn*2];
struct no
tree[maxn*4];
void lj(int t1,int t2)
void get(int k)
}int ask(int k,int l,int r)
int mid=(tree[k].l+tree[k].r)/2;
int u=inf;
if(l<=mid)u=min(u,ask(k*2,l,r));
if(r>mid)u=min(u,ask(k*2+1,l,r));
return u;
}void lian(int k,int l,int r,int v)
int mid=(tree[k].l+tree[k].r)/2;
if(l<=mid)lian(k*2,l,r,v);
if(r>mid)lian(k*2+1,l,r,v);
wh(k);
}int ss()
int main()
}int ans=dp[n];
for(int i=2;i<=k+1;i++)
}ans=min(ans,dp[n]);
}cout
}
2017 5 18 24 基站選址 失敗總結
先吐槽一下 學校太不厚道了,省賽掛了就不大給我們時間了,乙個題都不能好好做了 果然線段樹和dp到了zjoi都是怪物 這個題的題目描述非常有誘導性 對著錯誤的題目做了5天 乙個基站的範圍是指覆蓋它的範圍,而不是它覆蓋的範圍 以下是看錯題部分的思考 n 2k的dp通過模擬 劃分dp過程 可以發現 它只和...
ZJOI2010 基站選址
洛谷題目鏈結 真毒瘤 這個題目耗了我半天。結果是線段樹打錯了。回歸正題 線段樹 dp 首先當然是先考慮樸素 dp 啦,相信你既然都來做這題了,樸素的方程自然不用我多說,設 f i j 表示在前 i 個村莊內,第 j 個基站建在 i 處的最小費用 不考慮 i n 的賠償費用等 方程為 f i j mi...
題解 lg2605 基站選址
題面 設 f i,j 表示前 i 個村莊建立 j 個基站,且第 i 個村莊有基站的最小花費 則有 f i,j min 其中 cost k,i 表示第 i k 個村莊建有基站,中間沒有,所需要補償的費用 發現轉移式中從 j 1 j 我們可以脫去 j 這一維 考慮怎麼計算 cost k,i k i 如果...