【算法】01背包_部分背包

一、01背包问题
(1)题目:
01背包问题:(因为对每个物品只有选和不选两种情况,所以这个问题称为01背包)
有n个重量和价值分别为wi, vi的物品, 从这些物品中挑选出总重量不超过W的物品,求所有挑选方案中价值总和的最大值。
1 ≤ n ≤ 100I
1 ≤ wi, vi ≤ 100
1 ≤ W ≤ 10000

输入:
第一行物体个数n
第二行重量
第三行价值
第四行背包承装W
输出:
最大价值

样例:
输入:
4
2 1 3 2
3 2 4 2
5
输出:
7 (选择第0, 1, 3号物品)

(2)思路及其代码实现
思路一:动态规划
A、设初始总的最大价值为0 + f(W, 0)。
[f(W, 0)指的是从0号物品开始选择总重量≤W的总价值]
B、对于物品0,若选择,则总价值有 v0 + f(W - w0, 1);若不选择,则总价值有 0 + f(W, 1),此时当前的最大价值=max{v0 + f(W - w0, 1), 0 + f(W, 1)} ;
==>>
dp公式:dp[i][j] = 0 , (j == 0)
dp[i][j] = max{v[i] + dp[i - 1][j - w[i]], 0 + dp[i - 1][j]} (j > 0)
其中,i:表示行,代表可选第0——i个物品; j:表示列,代表背包剩余容量j;
tips: 按行解出dp[ ][ ],因为下一行的解依赖上一行的解。

/**
     * way01——动态规划dp解法
     * @param w
     * @param v
     * @param W
     * @return
     */
    private static int dp(int[] w,int[] v,int W) {
   
        int[][] dp = new int[w.length][W + 1];
//        初始化dp表的第一行
        for (int i = 0; i < W + 1; i++) {
   
            if (i >= w[0]) {
   //如果当前容量i装得下物体0
                dp[0][i] = v[0];
            }
        }
//        剩余行
        for (int i = 1; i < w.length; i++) {
   //行,代表可选第0——i个物品
            for (int j = 0; j < W + 1; j++) {
   //列,代表背包剩余容量j
                if (j >= w[i]) {
   
                    dp[i][j] = Math.max(v[i] + dp[i-1][j-w[i]], dp[i-1][j]);
                }
            }
        }
        return dp[v.length-1][W];
    }

思路二:深度优先搜索DFS

/**
     * way02——深度优先搜索DFS   O(2^n)
     *      遍历此搜索二叉树的所有分支,每个非叶子结点值==左右孩子的较大值
     * @param w 重量数组
     * @param v 价值数组
     * @param W 背包承重
     * @param current 当前判断物品下标 从0开始
     * @return
     */
    private static int dfs(int
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值