多重背包问题是背包问题中的一类,具体是指,给定一个背包的容积V,给定一列物品,以及其体积向量w[i],价值向量v[i]和个数向量s[i],也就是物品i的价值是v[i],有s[i]个,占用的体积是w[i],问在如何在保证背包装得下的情况下,最大可能装的物品的总价值是多少。
在多重背包问题中有一种经典的二进制优化,可以把枚举物品数量的过程从O(s)变成O(logs),也把多重背包问题转化成了0-1背包问题。此文的目的是给其中的数学基础给予证明。
命题:给定一个正整数x,和一个可重集合S={1,2,4,8,...,2k,r},其中2k+1−1≤x<2k+2。如果x>2k+1−1,则取r=x−(2k+1−1),此时S里有k+2个数;否则的话r=0,就把r从这列数中去掉,此时S里有k+1个数。需要注意的是,r有可能等于集合中的其他数。证明:任何属于1∼x的数,都可以表达为S中若干数字的和(每个数字最多只能取一次),且表法唯一。
证明:
先证明V={0,1,2,3,4,...,2k−1}是二元域F={0,1}上的线性空间,其有一组基为S={1,2,4,...,2k−1},其中V中的加法是模2k剩余类的加法,数乘是普通数字的乘法。
容易证明V关于模2k剩余类的加法是一个阿贝尔群,其余性质直接按照线性空间的定义验证即可,非常显然。接下来证明S确实是一组基。数学归纳法。当k=0的时候S=∅,成立,当k=1时也显然成立。假设当k=l时成立,当k=l+1时,由于已经知道{1,2,4,...,2l−1}是一组基,也就是线性无关的,由于2l>∑i=0l−12i=2l−1,所以2l无法由{1,2,4,...,2l−1}线性表出,所以{1,2,4,...,2l}线性无关。
接下来证明此线性无关向量组可以表出{0,1,2,...,2l+1−1}。由于∀x≤2l−1,由数学归纳法,都可以由{1,2,4,...,2l−1}线性表出,而对于任意满足2l≤x≤2l+1−1的x,都有0≤x−2l≤2l−1,所以x−2l可由{1,2,4,...,2l−1}线性表出,所以x可由{1,2,4,...,2l−1,2l}线性表出。由数学归纳法,证明完毕。
接下来证明原命题。如果n≤2k+1−1,那么由上面的命题,n可由S={1,2,4,...,2k}唯一线性表出,由于二元域F={0,1},所以当然最多取一次。r=0的情况已经被包含在上面。如果2k+1≤n≤x且r>0,则有2k+1−r≤n−r≤2k+1−1,由归纳法n−r能被S={1,2,4,...,2k}线性表出,所以n能被{1,2,4,...,2k,r}唯一线性表出。
这个命题还有非常简单的证明方法。取一个从V到k维01向量的同构映射,映射方式是二进制表示,然后所有命题都按照后者来证,一切都变得很显然,也不需要数学归纳法了。
由这个命题,我们可以对很多要枚举1∼n的问题进行优化,优化成logn的复杂度。树状数组就是其的一种应用。