二进制优化

在dp中,以多重背包为例:

  • 物品有 体积(v),价值(w),数量(s)三个属性
    当每一个物品dp时会在原有dp上根据数量(s)判断s倍次,而造成大量重复dp.

二进制分堆:

  • 就比如有数量为35的一组v,w相同的物品,就以
    (1+2+4+8+16+4)=(2^0)+(2^1)+(2^2)+(2^3)+(2^4)+(2^5)+剩余(4)=35
    分为堆
  • 将这s个相同物品根据二进制分堆后(注意分堆后剩余的数量也算一堆),在进行dp,虽然依然在重复dp,但dp次数会进行log(n)的优化(这里的log都是以2为底)

为什么会说依然在重复dp:

  • 因为分堆后,表面上分了堆之后的每个堆相当于不同的物品了,但因为每一个分堆后的物品的v和w都是相当于 (原物品)*(倍数) 后的加倍原物品,在dp时会以相同倍数体积回溯判断
  • 更直白就是 有(1~10)这10个数,要不能重复组装得到 9 这个数
    原:1+8,1+2+6,1+3+5,2+7,3+6,4+5,9
    二进制后:有 1,2,4,8,2(剩余) 这几个数
    现:1+8,1+2+2+4

为什么能用二进制:

  • 首先要知道的是每次dp数据迁移都是依赖于上一个的数据进行回溯判断
    比如 dp[v]=max(dp[v],dp[v-k]+value[k])
    在不优化的前提下将每个物品分为 1,2,...,s-1,s 一共s堆进行dp,其实就相当于枚举了该物品会被选多少个的所有可能性

  • 利用二进制把物品分为了 2^0,2^1,....,2^log(s-1),2^log(s) 一共logs堆,这log(s)堆并没有枚举所有可能,但在每次dp回溯时,其实就已经枚举了所有堆
    例如:s=10; 在没有优化分堆时就有10堆:1,2,3,4,5,6,7,8,9,10
    在二进制优化分堆后: 1,2,4,8,2(剩余堆)
    1=1 2=2 3=1+2 4=4 5=1+4 6=2+4 7=1+6都可以被二进制所表示

posted @ 2023-05-29 17:32  kd最棒  阅读(100)  评论(0)    收藏  举报