個人覺得這道題很難.......最近我要總結幾篇「dp系列」了。
令dp[i][j]表示,在第i個位置建造第j個基站時的最小代價。
為了方便,我們令n = n + 1,k = k + 1。給最後乙個點的c賦0,d和w都賦inf(0x3f3f3f3f,如果用0x7fffffff會爆int),這樣的好處是最後乙個站一定建造(否則inf就變成答案了,這數字也太大了),且計算進去了前n個的全部的代價。(可以腦補一下,如果做到f[n],那說明n建造了;如果沒做到f[n],那就有可能少算了一段的w;新增乙個節點可以幫我們簡化掉大量的分類討論)
方程:dp[i][j] = min(dp[ii][j - 1] + cost(ii + 1, i - 1)) + c[i] ii∈[1, i)
cost的計算無疑是最大的難點。
先假設我們對於每個迴圈的 j (每個 j 只會呼叫到 j - 1,可以滾動起來,每次迴圈到乙個新的基站數 j ,都給 j - 1的所有dp值按一定的法則建線段樹。這便是線段樹優化dp的思想)有這麼一棵滿足要求的線段樹,那直接取區間最小值進行轉移即可。
算cost要隨著轉移,向線段樹中加入。(這種隨操作而改變的做法是最難想到的!)
在我們轉移完了前i個村莊,即將處理下乙個時(i+1,但此時i還是i),對線段樹進行修改。
由於基站建造影響是有單調性的,即,以前剛好被i覆蓋到的(即i+1就夠不著了),現在不再會被覆蓋了。
然後又考慮到,既然右端不被覆蓋了,那麼左端再不被覆蓋,不就要交補償金了嗎?
左端不被補償是什麼呢?
於是求出每個節點可以被覆蓋的最長的一段,記為st~ed。
如果,轉移的量在st-1及以下,就夠不著了。
於是給線段樹上的1至st-1這段區間,全部增加乙個i節點的補償金。
這道題就解決了。
#include #include #define n 20010
#define inf 0x3f3f3f3f
using namespace std;
inline char gc()
return *s++;
}inline int read()
return x;
}void print(int x)
struct adj e[n];
int d[n], c[n], s[n], w[n], head[n], st[n], ed[n], f[n];
int n, k, cnt = 0;
inline void ins(int x, int y)
int val[n<<2], tag[n<<2];
inline void update(int p)
inline void pushdown(int p)
}void build(int p, int l, int r)
int mid = (l + r)>>1;
build(p<<1, l, mid); build(p<<1|1, mid + 1, r);
update(p);
}void modify(int p, int l, int r, int x, int y, int z)
pushdown(p); int mid = (l + r)>>1;
if(x <= mid) modify(p<<1, l, mid, x, y, z);
if(mid + 1 <= y) modify(p<<1|1, mid + 1, r, x, y, z);
update(p);
}int query(int p, int l, int r, int x, int y)
int main()
int ans;
for(int i = 1; i <= k; ++i)
ans = f[n];
}else
ans = min(ans, f[n]);
} }print(ans);
return 0;
}
ZJOI2010 基站選址
洛谷題目鏈結 真毒瘤 這個題目耗了我半天。結果是線段樹打錯了。回歸正題 線段樹 dp 首先當然是先考慮樸素 dp 啦,相信你既然都來做這題了,樸素的方程自然不用我多說,設 f i j 表示在前 i 個村莊內,第 j 個基站建在 i 處的最小費用 不考慮 i n 的賠償費用等 方程為 f i j mi...
bzoj 1835 ZJOI2010 基站選址
有n個村莊坐落在一條直線上,第i i 1 個村莊距離第1個村莊的距離為di。需要在這些村莊中建立不超過k個通訊基站,在第i個村莊建立基站的費用為ci。如果在距離第i個村莊不超過si的範圍內建立了乙個通訊基站,那麼就成它被覆蓋了。如果第i個村莊沒有被覆蓋,則需要向他們補償,費用為wi。現在的問題是,選...
P2605 ZJOI2010 基站選址
有n個村莊坐落在一條直線上,第i i 1 個村莊距離第1個村莊的距離為di。需要在這些村莊中建立不超過k個通訊基站,在第i個村莊建立基站的費用為ci。如果在距離第i個村莊不超過si的範圍內建立了乙個通訊基站,那麼就村莊被基站覆蓋了。如果第i個村莊沒有被覆蓋,則需要向他們補償,費用為wi。現在的問題是...