01背包打天下。

01背包 三维!- i w 01

  1. 记忆化递归 , 从n-1号开始,考虑与不考虑

    public int bestValue(int[] w,int[] v,int n,int c){  //尝试用 n号物品 填充 c的背包   记忆化nc即可。
        if(n<0 || c<=0){
            return 0;
        }else{
            int A = bestValue(w,v,n-1,c);                // 不考虑当前物品
    
            //考虑的时候 这个条件必不可少
            int B = 0;
            if(w[n]<=c){  //能放进去才能考虑。
                B = v[n] + bestValue(w,v,n-1,c-w[n]); // 考虑
            }
            return Math.max(A,B);
        }
    }
    
  2. DP

    1. 重量要作为数组的下标。 重点在这。要填满。

    2. 我习惯的选与不选数组

    3. dp[i] [w] [1] 就是 当前物品在w重量下 选择的最优解。

    4. 状态转移方程:

      1. dp[i][w][0] = Math.max(dp[i-1][w][0],dp[i-1][w][1]) //不选
        
      2. dp[i][w][1] = values[i] + Math.max(dp[i-1][w-weights[i]][0],dp[i-1][w-weights[i]][1])//选
        
      3. 很多我习惯的都可以合并。

    5. 二维DP 选与不选可合并。

      1. //F(i,c) = Max( F(i-1,c) , v(i)+F(i-1,c-w(i) )   //状态转移方程
        dp[i][w] = dp[i-1][w];// 不选
        if(w>=weights[i]){
              dp[i][w] = Math.max(dp[i-1][w],values[i]+dp[i-1][w-weights[i]]);  //选与不选合并。
        }
        
    6. 空间优化

      1. F(i,c) = Max( F(i-1,c) , v(i)+F(i-1,c-w(i) ) 状态转移方程

      2. 第i行只依赖于i-1行。 ,只需要保留两行数据。

      3. 不断的覆盖前一行内容。因为后面用不到了。

      4. 使用奇偶行即可。 i%2

        for(int i =1;i<weights.length;i++){
            for(int w=0;w<=C;w++){
            //F(i,c) = Max( F(i-1,c) , v(i)+F(i-1,c-w(i) )   //状态转移方程
                  dp[i%2][w] = dp[(i-1)%2][w];// 不选
                  if(w>=weights[i]){
                        dp[i%2][w] = Math.max(dp[(i-1)%2][w],values[i]+dp[(i-1)%2][w-weights[i]]);  //选与不选合并。
            }
          }
        }
        
    7. 空间再优化 二维转1维

      1. 思考,每次第二行更新的时候 只用到了第一行对应位置 左边的数据

      2. 那么我们就用一行,到第二个物品的时候,从右往左更新,那么就可以不断的刷新同一行即可。

      3. for(int i =1;i<weights.length;i++){  //只用到了左边的数据。右边不用,那么久可以从右往左更新。
            for(int w=C;w>=1;w--){
                  //F(i,c) = Max( F(i-1,c) , v(i)+F(i-1,c-w(i) )   //状态转移方程
                  dp[w] = dp[w-1];// 不选
                  if(w>=weights[i]){
                        dp[w] = Math.max(dp[w-weights[i]],values[i]+dp[w-weights[i]]);  //选与不选合并。 
                  }
              }
        }
        return dp[C];
        
    8. 题目升华,加上体积 ,那么多加一维就ok

posted @ 2021-01-07 11:26  逆风微笑的魔法师  阅读(61)  评论(0)    收藏  举报