01背包和完全背包一维数组遍历区别

我们先来讨论 01背包

     先看一下二维数组的遍历

                        f[i][j] 表示前i件物品,在容量不超过j的情况下的最大权值

                         n 表示种类, t 表示 容量 
                         w[MAXN]表示重量,v[MAXN]表示价值 
                                 for(i=1;i<=n;i++)
                                     for(j=w[i];j<=t;j++)
                                          dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);

                 01背包的关键两点: 1. 选与不选。

                                                   2. 前 i 件物品的 dp 情况,是由前  i-1 件物品的dp推出来的,不受本i件物品的dp的影响

     再看一维的遍历

                                 for(i=1;i<=n;i++)
                                       for(j=t;j>=w[i];j--)
                                           dp[j]=max(dp[j],dp[j-w[i]]+v[i]);

                       第二层循环的遍历就是为了满足上述的第二个条件。 我们先设  j1 > j2 ,更新dp[ j1  ] 肯定在 更新dp[ j2  ] 的前面,就算 j1- w[i] = j2 , 也不会受影响。 故在 第 i 层的循环下,可以保证各个dp[ j ] 是由 前 i -1 层 dp 推出来的,而不会受本次循环其他dp更新的影响。

                也可以用反证法,当第二层循环为递增循环时

                                for(i=1;i<=n;i++)                                // 完全背包
                                       for(j=w[i];j<=t;j++)
                                           dp[j]=max(dp[j],dp[j-w[i]]+v[i]);

                          也先设 j1 > j2 ,如果 j1 - w[i] == j2 . 而更新 dp[ j2 ] 在 dp [ j1  ] 前面,故 dp[ j1 ] 会受到 dp[ j2 ] 的影响。这与第二个条件不符。

  不过这与完全背包的条件相符  

                    for(i=1;i<=n;i++)
                                     for(j=w[i];j<=t;j++)
                                          dp[i][j]=max(dp[i-1][j],dp[i][j-w[i]]+v[i]);

                  完全背包的关键两点: 1. 可选有穷个。

                                                           2. 前 i 件物品的 dp 情况,是由前  i 件物品的dp推出来的,受本i件物品的dp的影响

                

猜你喜欢

转载自blog.csdn.net/hnlg311709000526/article/details/81503794
今日推荐