背包问题之0-1背包

0-1背包是最基本的背包问题,其核心思路就在于每个物品的放与不放(每个物品最多只能放一次)

一个最简单经典的0-1背包例题

题目

有 n 个物品和一个大小为 m 的背包. 给定数组 A 表示每个物品的大小和数组 V 表示每个物品的价值.

问最多能装入背包的总价值是多大?

样例

输入: m = 10, A = [2, 3, 5, 7], V = [1, 5, 2, 4]
输出: 9
解释: 装入 A[1] 和 A[3] 可以得到最大价值, V[1] + V[3] = 9

解题代码

public int backPackII(int m, int[] A, int[] V) {
    int[] dp = new int[m + 1];
    for(int i = 0;i < A.length;i++){//外层物品
        for(int j = m;j >= A[i];j--){//内层背包容量
            dp[j] = Math.max(dp[j - A[i]] + V[i],dp[j]);//当亲物品循环的每一个结果由上一个物品的循环结果转移而来,从而保证每个物品只使用一次。
        }
    }
    return dp[m];
}

再来一个例子

此例主要是为了体会不同的问题运用0-1背包思路解题时需要思考具体在dp数组中存什么?相应的状态转移方程怎么写。

题目

给出 n 个物品, 以及一个数组, nums[i] 代表第i个物品的大小, 保证大小均为正数, 正整数 target 表示背包的大小, 找到能填满背包的方案数。
每一个物品只能使用一次

解题代码

public int backPackV(int[] nums, int target) {
    int[] dp = new int[target + 1];
    int count = 0;
    dp[0] = 1;
    for(int i = 0;i < nums.length;i++){
        for(int j = target;j >= nums[i];j--){
            dp[j] = dp[j - nums[i]] + dp[j];//dp中存的是能够填满容量为i的背包的方案数
        }
    }
    return dp[target];
}
posted @ 2019-10-12 15:44  wunsiang  阅读(131)  评论(0编辑  收藏  举报