BZOJ 2287 消失之物 線段樹分治 揹包

2021-08-14 11:36:40 字數 1525 閱讀 9802

time limit: 10 sec  

memory limit: 128 mb

submit: 875  

solved: 499 [

submit][

status][

discuss]

ftiasch 有 n 個物品, 體積分別是 w1

, w2

, ..., wn

。 由於她的疏忽, 第 i 個物品丟失了。 「要使用剩下的 n - 1 物品裝滿容積為 x 的揹包,有幾種方法呢?」 -- 這是經典的問題了。她把答案記為 count(i, x) ,想要得到所有1 <= i <= n, 1 <= x <= m的 count(i, x) **。

第1行:兩個整數 n (1 ≤ n ≤ 2 × 103) 和 m (1 ≤ m ≤ 2 × 103),物品的數量和最大的容積。

第2行: n 個整數 w1

, w2

, ..., wn

, 物品的體積。

乙個 n × m 的矩陣, count(i, x)的末位數字。

3 21 1 2

1111

21如果物品3丟失的話,只有一種方法裝滿容量是2的揹包,即選擇物品1和物品2。 [

submit][

status][

discuss]

home

back

新年開的第一道題... 話說csdn又改版了?? 怎麼感覺就是像大白**靠攏啊. markdown介面變小不過全屏模式很爽啊, xhtml編輯模式更新了好評.

這道題可以用線段樹分治或者揹包做. 

那麼用揹包怎麼做呢? 我們看到這種限制很簡單的就要想到補集轉化辣. count(i, x)就是填滿體積為j的揹包的方案數 - 用了i號物品的填滿體積為j的揹包的方案數. 那麼設c[i][j]表示不用i號物品填滿體積為j的揹包的方案數, f[j]為填滿體積為j的揹包的方案數. 那麼用了i號物品的填滿體積為j的揹包的方案數怎麼算呢? 對於揹包問題我們其實可以在空間上限制來算. c[i][j - w[i]]實際上就表達了這種方案數. 因為我們只需要欽定最後乙個物品為i即可. 為什麼不是f[j - w[i]]? 因為有可能這種方案裡面也用了i. 那麼i就被用了兩次, 這是不合法的. 當w[i] < j的時候, c[i][j] = f[j], 因為不可能用到i號物品. 那麼我們就可以遞推完成此題辣.

實現過程中發現列舉i的時候c陣列只與當前i有關... 省掉一維xd.

#includeusing namespace std;

short n, m;

short a[2005], c[2005], f[2005];

int main()

for (i = 1; i <= n; ++ i, puts(""))

for (j = 1; j <= m; ++ j) printf("%d", c[j]);

}return 0;

}

BZOJ2287消失之物

dpdpdpdpdpdpdpdp 討厭dp 這道題看起來很難 實際上也很難 思路 我們要求拿走一件物品之後的方案數,那麼肯定會涉及到不拿走的情況,那麼不拿走的情況是什麼呢?用前i件物品拼成體積j的方案數,所以我們要先預處理一下這個初始陣列f i 也就是一件都不拿走的情況 之後呢?我們考慮如何轉移拿走...

BZOJ2287 消失之物 分治 DP

time limit 10 sec memory limit 128 mb submit status discuss ftiasch 有 n 個物品,體積分別是 w1 w2 wn 由於她的疏忽,第 i 個物品丟失了.要使用剩下的 n 1 物品裝滿容積為 x 的揹包,有幾種方法呢?這是經典的問題了。...

BZOJ 2287 消失之物 揹包DP

本來在寫暴力,寫著寫著突然就想到了這種做法 希望今年noi pnoip noip 的時候也能這樣 先不考慮某個物品消失的情況,也就是樸素的01揹包 rep i,1,n repd j,m,v i f j add f j f j v i 然後考慮第i ii物品消失之後,對答案的影響就是多了沒消失之前的累...