zoukankan      html  css  js  c++  java
  • 动态规划求解0-1背包问题

      0-1背包问题是: 一个背包能承受的最大容量为max_weight,  现在有n个物品, 它们的重量分别是{w1,w2,w3,......wn}, 和价值分别是{v1,v2,......vn}, 现在要求在满足背包装载的物品不超过最大容量的前提下,保证装载的物品的价值最大?

          动态规划求解过程可以这样理解:

      对于前i件物品,背包剩余容量为j时,所取得的最大价值(此时称为状态3)只依赖于两个状态。

      状态1:前i-1件物品,背包剩余容量为j。在该状态下,只要不选第i个物品,就可以转换到状态3。

      状态2:前i-1件物品,背包剩余容量为j-w[i]。在该状态下,选第i个物品,也可以转换到状态3。

      因为,这里要求最大价值,所以只要从状态1和状态2中选择最大价值较大的一个即可。 

       状态转换方程:

      dp( i,j ) = Max( dp( i-1, j ), dp( i-1, j-w[i] ) + v[i] )

      dp( i,j )表示前i件物品,背包剩余容量为j时,所取得的最大价值。 

      下面是java的demo代码:

    private int[] v;
    private int[] w;
    private static int[][] c;
    private int weight;
    
    private int[] flag = new int[5];
    
    public Greedy(int weight, int[] v, int[] w, int maxWeight) {
        this.w = w;
        this.v = v;
        this.weight = weight;
        this.c = new int[v.length][this.weight + 1];
    }
    
    public void solve() {
        int len = w.length;
    
        for (int i = 1; i < len; i++) {
            for (int j = 1; j <= weight; j++) {
    
                //第i件物品要么放,要么不放
                //如果第i件物品不放的话,就相当于求前i-1件物体放入容量为j的背包获得的最大价值
                //如果第i件物品放进去的话,就相当于求前i-1件物体放入容量为j-w[i]的背包获得的最大价值
                if (w[i] > j) {
                    c[i][j] = c[i - 1][j];
                } else {
                    // j > w[i]
                    if (c[i - 1][j] > c[i - 1][j - w[i]] + v[i]) {
                        c[i][j] = c[i - 1][j];
                    } else {
                        c[i][j] = c[i - 1][j - w[i]] + v[i];
                    }
                }
            }
        }
    
        //下面求解哪个物品应该放进背包
        int i = v.length - 1, j = weight;
        while (c[i][j] != 0) {
    
            if (c[i - 1][j - w[i]] + v[i] == c[i][j]) {
                flag[i] = 1;
                j = j - w[i];
                i--;
            }
        }
    
        for (i = 1; i < v.length; i++) {
            if (flag[i] == 1) {
                System.out.print("重量" + w[i]);
                System.out.println("价值为" + v[i]);
            }
        }
    }
    
    public static void main(String[] args) {
        int[] v = {0, 4, 5, 6};
        int[] w = {0, 3, 4, 5};
    
        int weight = 10;
        Greedy knapsack = new Greedy(weight, v, w, weight);
        knapsack.solve();
    }

      

  • 相关阅读:
    12 Source Code Profilers for C & C++
    HttpWebRequest的使用方法
    MSDN Windows 下载
    Qt 4.7 在VS2010环境下的编译
    [转].NET Logging Tools and Libraries
    硬盘崩溃之后
    .net core 下使用 logdashboard 日志面板
    工具收藏 年终工作总结必备工具之ppt利器
    Dapper 的应用和Dapper.Contrib 的方法封装(一)
    Dapper 的应用和Dapper.Contrib 的方法封装(二)
  • 原文地址:https://www.cnblogs.com/xjz1842/p/5994140.html
Copyright © 2011-2022 走看看