背包优化

来源:互联网 发布:crontab java 编辑:程序博客网 时间:2024/05/21 09:03

多重背包优化一

•看做有N组物品,放入容量为j的背包,对于每组物品,选择放入的数量k(0…n[i])
•对于第i种物品,放入容量为j的背包

f[j+k*c[i]] = max{f[j+k*c[i]],f[j]+k*w[i]}

•j= 0: c[i], 2*c[i], 3*c[i],..., n[i]*c[i]
•j= 1: 1+c[i], 1+2*c[i]...
•j= c[i]: 2*c[i],3*c[i]...
•如果f[c[i]]中放入了c[i],j=0 与 j=c[i]完全重复
•一种优化,如果f[j]被更新过了,那就跳过此次循环

多重背包优化二(仅限于可行性问题)

•和完全背包相比,物品的数量是有限的,尽量节省地使用物品i
•g[i][j],记录物品i,在容量为j,达到最优值时,使用的最少数量
•如果之前物品能够在容量为j时达到最优值,那就不用使用物品i了
•f[i][j]=max{f[i-1][j],f[i][j-c[i]]+w[i]}
•g[i][j]= 0,                   f[i][j] =f[i-1][j]
•             g[i][j-c[i]]+1,  f[i][j] = f[i][j-c[i]]+w[i]  
•fori = 1 to N
•    g[0…V] = 0
•    for j = 0 to V
•         if g[j-c[i]] + 1 > n[i] continue
•          if f[j-c[i]]+w[i] > f[j]
•               f[j] = f[j-c[i]]+w[i]
•               g[j] = g[j-c[i]] + 1
•时间复杂度O(NV)

开始以为这种想法可以用于求最值的多重背包,后来学长给出反例:

”如果 g[j - v[i]] + 1 > c[i] 
这个时候 不能从转移 dp[j - v[i]] + w[i] 
这个一定是对的么 
万一 dp[j - v[i]] 的最优值 是用了 c[i] 个得到的 
但是如果我在 dp[j - v[i]] 处用用了 c[i] - 1 个 
那个不是最优值 
但是 转移到 dp[j - v[i]] + w[i] 
可以得到比 dp[j] 更优的怎么办呢 “

...还真没办...写下交了道水题,果断WA掉了...

想想,这种转移违背了最优子结构的性质,子问题最优,但原问题不定最优


多重背包优化三

就是比较常见的单调队列优化

单调队列优化,一般就是证明,对于i ,任意的j<i,  都有F(i) > F(j),则小于i的都不用考虑,从而减少枚举的决策数

详细讲解见http://www.cppblog.com/flyinghearts/archive/2010/09/01/125555.html

更多的关于单调队列优化的见http://wenku.baidu.com/view/ef259400bed5b9f3f90f1c3a.html

原创粉丝点击