ftiasch 有 n 個物品, 體積分別是 w1, w2, ..., wn。 由於她的疏忽, 第 i 個物品丟失了。 「要使用剩下的 n - 1 物品裝滿容積為 x 的揹包,有幾種方法呢?」 -- 這是經典的問題了。她把答案記為 count(i, x) ,想要得到所有1 <= i <= n, 1 <= x <= m的 count(i, x) **。
view code
輸入格式
第1行:兩個整數 n (1 ≤ n ≤ 2 × 103) 和 m (1 ≤ m ≤ 2 × 103),物品的數量和最大的容積。
第2行: n 個整數 w1, w2, ..., wn, 物品的體積。
輸出格式
乙個 n × m 的矩陣, count(i, x)的末位數字
樣例樣例輸入
3 2
1 1 2
樣例輸出
11
1121
。。。我也不知道我是怎麼想到的,只記得一開始我打了個o(n2mlogn)的**交上後比暴力還慢。。。。
由此想到:合併揹包的複雜度為n2,所以與其合併揹包還不如乙個乙個地新增元素,由此可以想到:我們
考慮每個物品對複雜度的貢獻,期望為mlogn,那麼是不是可以用分治?so:假如我們有一棵線段樹,在
每乙個結點開乙個揹包,怎麼用呢?考慮每個物品對答案的貢獻,對線段樹的沒個非葉子節點:
假設某個節點控制範圍為l到r,則mid=l+r>>1;(廢話)那麼(l,mid)範圍內所有的點會對(mid+1,r)
的答案作出貢獻,所以把(l,mid)內每個物品單獨取出,加入到rc的揹包中,並且在考慮以rc為根的子樹時
把rc的揹包下傳以傳遞貢獻,下傳時直接memcpy即可;在葉子節點統計答案,直接輸出
1 #include 2感謝loj碼風優化(貌似某位壓行大神也寫過?)#define n 2003
3#define reg register
4using
namespace
std;
5int
n, m;
6int
w[n];
7int
pos[n];
8int f[n << 2
][n];
9void ask(const
int g, const
int l, const
intr)
14const
int mid = l + r >> 1, lc = g << 1, rc = g << 1 | 1
;15 f[lc][0] = f[rc][0] = 1;16
for (int i = 1; i <= m; ++i) f[lc][i] = f[rc][i] =f[g][i];
17for (reg int i = mid + 1; i <= r; ++i) 22}
23for (reg int i = l; i <= mid; ++i) 28}
29ask(lc, l, mid);
30 ask(rc, mid + 1
, r);31}
32int
main()
40 }
優化:1.其實不必在所有節點開揹包,在每層開乙個即可;
2.到達葉子節點可直接輸出答案,不必最後統計輸出;
BZOJ2287 消失之物 分治 DP
time limit 10 sec memory limit 128 mb submit status discuss ftiasch 有 n 個物品,體積分別是 w1 w2 wn 由於她的疏忽,第 i 個物品丟失了.要使用剩下的 n 1 物品裝滿容積為 x 的揹包,有幾種方法呢?這是經典的問題了。...
POJ Challenge消失之物
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...
消失之物 s 題解
是不是很熟悉的開頭,哈哈,畢竟乙隻蒟蒻第一次寫題解多少有點緊張啊 本題來自hloj 1949 好了,切入正題 題面意思呢,就是給你n個物品,乙個m的揹包,接下來是w i 表示每個物品的重量,看起來很簡單,不過呢,有乙個物品丟了,你要輸出乙個 橫排的數值表示丟了第i個物品,縱列的數值表示要來填滿乙個容...