求解01背包问题(Java)

题目描述

实现一个算法求解 01 背包问题。背包问题的介绍如下:
• 已知一个容量为 totalweight 的背包,有不同重量不同价值的物品,问怎样在背包容量限制下达到利益最大化。
• 01 背包问题要求每个物品只有一个,可以选择放入或者不放入背包。
背包问题求解方法的介绍如下:
• 用符号 Vi 表示第 i 个物品的价值,Wi 表示第 i 个物品的体积,Vi,j 表示当前背包容量为 j 时,前 i 个物品最佳组合对应的价值。
• 对于当前第 i 个商品,如果包的容量比该物品体积小,即 j<Wi。那么此时的价值与前 i−1 个的价值是一样的,即 Vi,j=Vi−1,j。
• 对于当前第 i 个商品,如果包的容量能够装下该物品,即 Wi≤j。此时需要判断装或者不装这个物品的价值对比,
选择使价值更大的情况,即 Vi,j=max(Vi+Vi−1,j−Wi,Vi−1,j)。

通过最优解回溯法找到解的组成:
• 当 Vi,j=Vi−1,j时,说明没有选择第 i 个物品。
• 当 Vi,j=Vi−1,j−Wi 时,说明装了第 i 个商品。
• 从 i,j 的最大值一直遍历到 i=0 ,则找到了所有解。

输入描述
第一行为两个数字 totalweight、N,均不超过 1000。totalweight 含义见题干,N 为物品数量。
接下来 N 行,每行两个数字 Wi、Vi,均不超过 1000。含义见题干。

输出描述
输出一行,为在背包容量限制下的最大化利益。

输入输出样例

8 5
3 4
5 5 
1 2
2 1
2 3

输出
10

运行限制
• 最大运行时间:1s
• 最大运行内存: 256M

代码演示

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        int tw = scan.nextInt();//记录物品总重量
        int n = scan.nextInt();
        int[] w = new int[n+1];//记录第i个物品重量
        int[] v = new int[n+1];//记录第i个物品的价值
        for(int i = 1;i <= n;i++){//录入数据
            w[i] = scan.nextInt();
            v[i] = scan.nextInt();
        }

        int[][] dp = new int[tw+1][tw+1];//记录当背包总重量为i时,装入背包中物品的最大价值
        for(int i = 1;i <= n;i++){//i表示第i个物品的重量
            for(int j = 1;j <= tw;j++){//j表示背包总重量
                if(j < w[i]){//当背包总重量为j时,物品的重量大于背包的总重量,则背包物品的总价值为:dp[i-1][j]
                    dp[i][j] = dp[i-1][j];
                }
                /**
                 * 当背包总重量为j时,物品的重量小于等于背包的总重量,则背包物品的总价值为: Math.max(v[i]+dp[i-1][j-w[i]],dp[i-1][j])
                 *
                 */
                if( j >= w[i]){
                    dp[i][j] = Math.max(v[i]+dp[i-1][j-w[i]],dp[i-1][j]);
                }
            }
        }

        //输出
        System.out.println(dp[n][tw]);

        scan.close();
    }
}

以题目例子用二维表表示

最后的最大值根据判断条件:

dp[5][8] = dp[4][6] + 3 =10;

对于当前第 i 个商品,如果包的容量比该物品体积小,即 j < w[i]。那么此时的价值与前 i−1 个的价值是一样的,即 dp[i][j] = v [i-1][j]

对于当前第 i 个商品,如果包的容量能够装下该物品,即 w[i] ≤ j。此时需要判断装或者不装这个物品的价值对比,选择使价值更大的情况,即 dp[i][j] =Math.max(v[i] + dp[i-1][j-w[i]] , dp[i-1][j])

之后的完全背包、多重背包、分组背包都在此基础上演变

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值