zoukankan      html  css  js  c++  java
  • 动态规划 背包问题

    问题描述:

    我们有一个背包,背包总的承载重量是 Wkg。现在我们有 n 个物品,每个物品的重量不等,并且不可分割。我们现在期望选择几件物品,装载到背包中。在不超过背包所能装载重量的前提下,如何让背包中物品的总重量最大?

    具体例子:小明有个背包,最大装9kg物品,现在桌上有几个物品,重量(kg)分别是2,2,4,6,3  问,小明包里能装的最大多少kg?

    private static  int[] weight = {2,2,4,6,3};  // 物品重量
    private static int n = 5; // 物品个数
    private static int w = 9; // 背包承受的最大重量
    代码如下:
    weight:物品重量,n:物品个数,w:背包可承载重量
    public int knapsack(int[] weight, int n, int w) {
      boolean[][] states = new boolean[n][w+1]; // 默认值false
      states[0][0] = true;  // 第一行的数据要特殊处理,可以利用哨兵优化
      if (weight[0] <= w) {
        states[0][weight[0]] = true;
      }
      for (int i = 1; i < n; ++i) { // 动态规划状态转移
    //--其实就是把states[i-1][j] 的数据,copy到下一个状态states[i],应为下一个状态要使用本次states做重量累加 for (int j = 0; j <= w; ++j) {// 不把第i个物品放入背包 if (states[i-1][j] == true) states[i][j] = states[i-1][j]; }
    //这里做重量判断,没超过背包重量就塞进包里,j+weight[i]其实j代表的是背包当前的重量,+weight[i]
    for (int j = 0; j <= w-weight[i]; ++j) {//把第i个物品放入背包 if (states[i-1][j]==true) states[i][j+weight[i]] = true; } } for (int i = w; i >= 0; --i) { // 输出结果 if (states[n-1][i] == true) return i; } return 0; }

    还可以使用一维数组解决该问题:

        //使用一维数组
        public static int knapsack2(int[] items, int n, int w) {
            boolean[] states = new boolean[w+1]; // 默认值false
            states[0] = true;  // 第一行的数据要特殊处理,可以利用哨兵优化
            if (items[0] <= w) {
                states[items[0]] = true;//这里是哨兵,不写这个其实也可以
            }
            for (int i = 1; i < n; ++i) { // 动态规划
                for (int j = w-items[i]; j >= 0; --j) {//把第i个物品放入背包(这里倒着从w-items[i]判断,可以避免重复计算)
                    System.out.println("i="+i+"	j="+j+"	states[j]="+states[j]+"	items[i]="+items[i]);
                    if (states[j]==true) states[j+items[i]] = true;
                    System.out.println(Arrays.toString(states));
                }
            }
            for (int i = w; i >= 0; --i) { // 输出结果
                count++;
                if (states[i] == true) return i;
            }
            return 0;
        }
  • 相关阅读:
    打开安装 好的Microsoft Dynamics CRM 4.0 报错误为 Caller does not have enough privilege to set CallerOriginToken to the specified value 的解决办法
    基于 Windows Server 2008 的计算机对 Microsoft Dynamics CRM 4.0 的支持
    Microsoft Dynamics CRM 4.0 如何添加自定义按钮
    Microsoft Dynamics CRM 4.0 Plugin 取值,赋值,查询
    C# 中的 enum(枚举) 类型使用例子
    vue事件的绑定
    表单验证2
    node中模块
    node模块的引入
    node中的读文件
  • 原文地址:https://www.cnblogs.com/yanghaolie/p/13851863.html
Copyright © 2011-2022 走看看