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物品消失之後,對答案的影響就是多了沒消失之前的累...