《DP学习系列》从零开始学习动态规划,二维背包(五)

1. 问题

二维费用的背包问题是指:对于每件物品,具有两种不同的费用,选择这件物品必须同时付出这两种费用。对于每种费用都有一个可付出的最大值(背包容量)。问怎样选择物品可以得到最大的价值。设第i件物品所需的两种费用分别为Ci和Di。两种费用可付出的最大值(也即两种背包容量)分别为V 和U。物品的价值为Wi。

  比较简单的理解,就是增加一维物品质量。现在不仅要考虑物品占背包的体积,还有考虑物品本身的质量,最后保证背包中物品的价值最大。

2. 基础实现

  背包九讲这里没有给出伪代码,留给读者去实现。笔者的实现如下:

01 二维背包

F [ i , v , u ] = m a x { F [ i 1 , v C i , u D i ] + W i , F [ i 1 , v , u ] }

//滚转数组优化成二维
F[0...V][0...U]
//现在最优子结构为u,v情况下的最大价值,在u或者v任何一个等于0时,初始值都为0
F[0][0...U]=0
F[0...V][0]=0

for i=0 to N
    for v=V to Ci
        for u=U to Di
            F[v][u]=max{F[v-Ci][u-Di]+Wi,F[v][u]} 

完全二维背包

F [ i , v , u ] = m a x { F [ i 1 , v k C i , u k D i ] + k W i } , 0 k m i n { V / C i , U / D i }

//滚转数组优化成二维
F[0...V][0...U]
F[0][0...U]=0
F[0...V][0]=0
for i=0 to N
    for v=Ci to V
        for u=Di to U
            F[v][u]=max{F[v-Ci][u-Di]+Wi,F[v][u]} 

多重二维背包

F [ i , v , u ] = m a x { F [ i 1 , v k C i , u k D i ] + k W i } , 0 k M i

F[0...N][0...V][0...U]
//现在初始条件为i,v,u下的最大价值,初始状态要正确定义。
F[0][0...N][0...V]=0
F[0...N][0...V][0]=0
F[0...N][0][0...V]=0

for i=0 to N
     for v=0 to V
        for u=0 to U
            for k=0 to log(Mi)
                F[i][v][u]=max{F[i-1][v-2^k*Ci][u-2^k*Di]+2^k*Wi,F[i-1][v][u]} 

3. 物品总个数的限制

  如果按照笔者的思考,对每个物品的限制可以直接加在多种背包的Mi上。比如:A物品总共10件,限制最多只能拿3件( V / C A 10 ),那么此时可以将Mi由原来的10更新为3。
  崔从另外的角度思考:最多拿3件成了另外一维的限制,可以使用上文中伪代码解决这个问题。

4. 复整数域上的背包问题

  简单的来思考还是二维的本质,背包九讲未给出伪代码。现在笔者针对01二维背包思考如下(复数用 a + b I 表示):

F [ i , v ] = m a x { F [ i 1 , v ( C i + D i I ) ] + W i , F [ i 1 , v ] }

//复数F[V]分成F[实部][虚部]
F[0...V][0...U]
//现在最优子结构为u,v情况下的最大价值,在u或者v任何一个等于0时,初始值都为0
F[0][1...U]=0
F[1...V][0]=0

for i=0 to N
    for v=V to Ci
        for u=U to Di
            F[v][u]=max{F[v-Ci][u-Di]+Wi,F[v][u]} 

5. 小结

  最后崔强调了将一些问题增加的限制当成新的一维来解决,此时又将新问题转化成旧问题。回顾下DP问题的两个必要特征最优子结构和无后效性,从状态转移我们确定最优子结构的成立,无后效性从状态转移方程也能确认没有问题,但是for遍历循序可能破坏无后效性,这里关键的i从0到N,确保了无后效性。
  另外DP最近笔者做的题来感觉,只能解决最优问题。比如最长回文子串问题,机器人走方格问题等。DP和贪婪最直观的不同就是DP从逻辑上保证全局最优(通过状态转移方程和最优子结构保证这一点),而贪婪只是局部最优,如Dijkstra算法、Prim算法、Kruskal算法(DSAA学到了还没有开始记录)等。如果使用DP去求最优解的全集,这是不可能的(除非初始条件有多个最优解)。
  

猜你喜欢

转载自blog.csdn.net/lovestackover/article/details/80637067