2019金华Day18-dp专项

经典揹包问题

01揹包和无限揹包略过
多重揹包的优化
这能优化到O(nm)O(nm)?!
((我们以求方案数为例))
设第i种物品有c[i]c[i]个,重量为w[i]w[i]
f[i][j]​=​k=0c[i]​f[i​​1][j​​kw[i]]f[i][j]\!=\!\sum_{k=0}^{c[i]}\!f[i\!-\!1][j\!-\!k\cdot w[i]]
这是最基本的暴力,然后考虑优化
我们写一个类似前缀和的东西
g[i][j]​=​f[i​​1][j]+g[i​​1][j​​w[i]]g[i][j]\!=\!f[i\!-\!1][j]+g[i\!-\!1][j\!-\!w[i]]
那么f[i][j]​=​g[i][j]g[i][j​​(k[i]​+​1)w[i]]f[i][j]\!=\!g[i][j]-g[i][j\!-\!(k[i]\!+\!1)\cdot w[i]]
自此可以优化到O(nm)O(nm)
Ps:Ps:若用二进制拆分来优化,就不能统计方案,比如说对于5会拆成{1,2,2},那么再算选两个时就会统计两次。
小习题:
1. 考虑01揹包问题,有Q种操作,每次加入一种物品或删除一种物品,每次操作完后输出不超过S的方案数
n,Q,S​​2000n,Q,S\!\leq\!2000
我们假设这个数重量为ww
对于加入这个数的操作:
for i​:​S downto wf[i]+​=f[iw] for\ i\!:\!S\ downto\ w\\ f[i]+\!=f[i-w]
对于删除这个数的操作:
for i​:​w to Sf[i]​=f[iw] for\ i\!:\!w\ to\ S\\ f[i]-\!=f[i-w]
时间复杂度:O(nS):O(nS)
2. 树上依赖01揹包:如果儿子选了,则父亲必须要选
这是一个很强的限制
思考后就会发现,这相当于在树上选择一个包含根节点的连通块
那么我们通过dfs序把原问题转化到序列上
我们设f[i][1]f[i][1]表示选第ii个点,f[i][0]f[i][0]表示不选第ii个点
考虑f[i][1]f[i][1]的转移 f[i][1]+​=​f[fa[i]][1]f[i][1]+\!=\!f[fa[i]][1]
考虑f[i][0]f[i][0]的转移 f[i][0]+​=​f[ed[i]1][0]f[i][0]+\!=\!f[ed[i]-1][0]
((未完待续))

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章