算法——0-1背包问题

动态规划之0-1背包问题(详解+分析+原码) 本篇文章将介绍算法专题之动态规划中的背包问题,更准确的说是背包问题中最简单的一种类型,即0-1背包问题,就是给你一定容量的背包和若干物品,每种物品只能选一次,告诉你每件物品的价值和体积,求背包里面物品的最大总价值。 阅读详情

题目描述

有一个容量为 N 的背包,要用这个背包装下物品的价值最大,这些物品有两个属性:体积 w 和价值 v。

解题思路

记忆化搜索

/// 背包问题
/// 记忆化搜索
/// 时间复杂度: O(n * C) 其中n为物品个数; C为背包容积
/// 空间复杂度: O(n * C)
public class Solution {

    private int[][] memo;

    public int knapsack01(int[] w, int[] v, int C) {

        int n = v.length;
        memo = new int[n][C + 1];
        Arrays.fill(memo, -1);
        return bestValue(w, v, n - 1, C);

    }

    //用 [0..index] 的物品,填充容积为 c 的背包的最大价值
    private int bestValue(int[] w, int[] v, int index, int c) {

        if (index < 0 || c <= 0) {
            return 0;
        }

        if (memo[index][c] != -1) {
            return memo[index][c];
        }
        
        // 不考虑index 直接考虑,index - 1的价值
        int res = bestValue(w, v, index - 1, c);
        if (c >= w[index]) {
            res = Math.max(res, v[index] + bestValue(w, v, index - 1, c));
        }

        memo[index][c] = res;
        
        return res;
    }
}

动态规划

/// 背包问题
/// 记忆化搜索
/// 时间复杂度: O(n * C) 其中n为物品个数; C为背包容积
/// 空间复杂度: O(n * C)
public class Solution {

    public static int knapsack01(int[] w, int[] v, int C) {
        if (w == null || v == null || w.length != v.length) {
            throw new IllegalArgumentException("Invalid w or v");

        }
        int n = w.length;
        if (n == 0 || C == 0) {
            return 0;
        }
        int[][] memo = new int[n][C + 1];

        //先确定最基本的情况
        for (int j = 0; j <= C; j++) {
            memo[0][j] = (j >= w[0] ? v[0] : 0);
        }
        for (int i = 0; i < n; i++) {
            memo[i][0] = 0;
        }

        for (int i = 1; i < n; i++) {
            for (int j = 0; j <= C; j++) {
                //1.物品i不放入背包中,所以c[i][j]为c[i-1][j]的值
                memo[i][j] = memo[i - 1][j];
                //2.物品i放入背包中,则背包剩余重量为j-w[i],所以c[i][j]为c[i-1][j-w[i]]的值加上当前物品i的价值
                if (j >= w[i]) {
                    memo[i][j] = Math.max(memo[i][j], v[i] + memo[i - 1][j - w[i]]);
                }
            }
        }

        return memo[n - 1][C];
    }

    public static void main(String[] args) {
        int m = 10;
        int w[] = {3, 4, 5};
        int p[] = {4, 5, 6};
        int c = knapsack01(w, p, m);
        System.out.println(c);
    }
}

动态规划-优化空间

import java.util.Arrays;

/// 背包问题
/// 记忆化搜索
/// 时间复杂度: O(n * C) 其中n为物品个数; C为背包容积
/// 空间复杂度: O(n * C)
public class Solution {

    public static int knapsack01(int[] w, int[] v, int C) {
        if (w == null || v == null || w.length != v.length) {
            throw new IllegalArgumentException("Invalid w or v");

        }
        int n = w.length;
        if (n == 0 || C == 0) {
            return 0;
        }
        //每次计算新的 memo 时只需用到上一个 memo,因此只需 2 行就行了
        int[][] memo = new int[2][C + 1];

        //先确定最基本的情况
        for (int j = 0; j <= C; j++) {
            memo[0][j] = (j >= w[0] ? v[0] : 0);
        }

        for (int i = 0; i < n; i++) {
            memo[i % 2][0] = 0;
        }

        for (int i = 1; i < n; i++) {
            for (int j = 0; j <= C; j++) {
                //1.物品i不放入背包中,所以c[i][j]为c[i-1][j]的值
                memo[i % 2][j] = memo[(i - 1) % 2][j];
                //2.物品i放入背包中,则背包剩余重量为j-w[i],所以c[i][j]为c[i-1][j-w[i]]的值加上当前物品i的价值
                if (j >= w[i]) {
                    memo[i % 2][j] = Math.max(memo[i % 2][j], v[i] + memo[(i - 1) % 2][j - w[i]]);
                }
            }
        }

        return memo[(n - 1) % 2][C];
    }

    public static void main(String[] args) {
        int m = 10;
        int w[] = {3, 4, 5};
        int p[] = {4, 5, 6};
        int c = knapsack01(w, p, m);
        System.out.println(c);
    }
}

动态规划-优化空间(一维数组)

/// 背包问题
/// 动态规划改进: 滚动数组
/// 时间复杂度: O(n * C) 其中n为物品个数; C为背包容积
/// 空间复杂度: O(C), 实际使用了2*C的额外空间
public class Solution1 {

    public int knapsack01(int[] w, int[] v, int C) {

        if (w == null || v == null || w.length != v.length)
            throw new IllegalArgumentException("Invalid w or v");

        if (C < 0)
            throw new IllegalArgumentException("C must be greater or equal to zero.");

        int n = w.length;
        if (n == 0 || C == 0) {
            return 0;
        }


        int[][] memo = new int[2][C + 1];

        for (int j = 0; j <= C; j++) {
            memo[0][j] = (j >= w[0] ? v[0] : 0);
        }


        for (int i = 1; i < n; i++) {
            for (int j = 0; j <= C; j++) {
                memo[i % 2][j] = memo[(i - 1) % 2][j];
                if (j >= w[i])
                    memo[i % 2][j] = Math.max(memo[i % 2][j], v[i] + memo[(i - 1) % 2][j - w[i]]);
            }
        }


        return memo[(n - 1) % 2][C];
    }

    public static void main(String[] args) {

    }
}
背包问题之0-1背包算法详解 一、0-1背包问题描述 有5件物品和1个背包,背包最多只能装下8公斤的物品。怎样选择物品,使得背包能装下并且得到的价值最大。物品的重量和价值如下所示: 物品1: 6公斤   价值48元 物品2: 1公斤   价值7元 物品3: 5公斤   价值40元 物品4: 2公斤   价值12元 物品5: 1公斤   价值8元 阅读详情

相关推荐

遗传算法求解 0-1背包问题

0-1背包问题 如何把这些物品发入这个有承重质量质量限制的背包中,在不超出背包最大限制的前提下,使得放入背包中的物品总价值最大。 1、问题描述 已知 l 个物品的质量及其价值分别为Wi(i=1,2,3…)和Vi(i=1,2,3…),背包的最大载重量为C。 则0-1背包问题可被描述为:选择哪些物品放入背包,使得背包在最大载重量限制之内所装物品的总价值最大? 0-1背包问题的数学模型如下:  max⁡∑i=1lvixi (1)\ \max\sum_{i=1}^{l}{v_ix_i}\tag{1}\,&

weixin_42394252的博客 7798

九种 0-1 背包问题详解

目录 动态规划概念 问题1:0-1背包问题 问题2:完全背包问题 问题3:多重背包问题 问题4:混合背包问题 问题5:二维背包问题 问题6:分组背包问题 问题7:有依赖的背包问题(困难) 问题8:背包问题求方案数 问题9:背包问题求具体方案 前言 0-1 背包是一个经典的问题,之前也整理过一篇关于 0-1 背包的博客,当时只是整理了 0-1 背包问题的4 种解决方法。最近在复习算法,发现有很多 0-1 背包问题的衍生问题。0-1 背包问题的限制条件既可以是重量,也可以是容量,或者..

Tyler_Zx的博客 2万+

MATLAB--基于PSO算法的0-1背包问题的求解

MATLAB–基于PSO算法的0-1背包问题的求解。 0-1背包问题是与TSP问题相似的优化算法测试问题,具体描述为:有N件物品和一个容量为v的背包。第i件物品的体积是 ,价值是 。求解将哪些物品放入背包可使物品的体积总和不超过背包的容量,且价值总和最大。 在这里,假设物品数为10,背包的容量为300,每件物品的体积为[95,75,23,73,50,22,6,57,89,98],每件物品的价值为[...

向着怪阿姨拔足狂奔的博客 4506

背包问题详解(01背包,完全背包,多重背包,分组背包)

有 N 件物品和一个容量是 V的背包。每件物品只能使用一次。第 i 件物品的体积是 vi,价值是 wi。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。输入格式第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。输出格式输出一个整数,表示最大价值。数据范围0

走在努力路上的自己的博客 6万+

算法0-1背包问题

算法设计分析0-1背包问题 算法描述 0-1背包问题是子集选取问题。一般情况下,0-1背包问题是NP难的。0-1背包问题的解空间可用子集树表示。解0-1背包问题的回溯法与装载问题的回溯法十分类似。在搜索解空间树时,只要其左儿子结点是一个可行结点,搜索就进入其左子树。当右子树有可能包含最优解时才进入右子树搜索;否则将右子树剪去。设r是当前剩余物品价值总和;cp是当前价值;bestp是当前最优价值。当ep+r<=bestp时,可剪去右子树。计算右子树中解的上界的更好方法是将剩余物品依其单位重量价值排序,然

qq_51344334的博客 1709

0019算法笔记——【动态规划】0-1背包问题

1、问题描述:      给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问:应如何选择装入背包的物品,使得装入背包中物品的总价值最大?      形式化描述:给定c >0, wi >0, vi >0 , 1≤i≤n.要求找一n元向量(x1,x2,…,xn,), xi∈{0,1}, ∋ ∑ wi xi≤c,且∑ vi xi达最大.即一个特殊的整数规划问题。

liufeng_king的专栏 6万+

背包问题——01背包|完全背包

01背包你真的都会吗?各位佬们还不进来看看?

冷兮雪的博客 3万+

算法——动态规划之0-1背包问题

打算每天复习一点算法内容,就先从动态规划下手。曾经动态规划让我头疼,重新学了一下觉得还好啦不是很难,实现动态规划算法的核心在于实现它的递推公式,写出递推公式,代码也就很容易了。动态规划类似分治法,都是将一个大问题分解为一个个小问题,分而治之。不同之处在于,动态规划记忆了重复的子问题,避免了运算过程中的重复计算。适用情况:有重叠子问题和最优子结构性质(动态规划每一步求的都是最优解)的问题。下面我们通...

Astar的博客 1万+

0-1 背包问题的 4 种解决方法&&算法策略

蛮力法 递归与分治策略 动态规划 贪心算法 回溯法 分支限界法 前言 0-1背包是一个经典的问题,而它能用不同的算法思想去解决。恰巧最近在看算法,学习算法就是学习解决问题的思路。现在将0-1背包问题与解决方法整理出来,这样不仅能区分不同的算法思想,还能加深对0-1背包问题的理解。虽然有的算法思想并不能解决这一问题,但是为了对算法策略有一个较为整体的了解,所以在这里做一下简单的介绍。 ...

Tyler_Zx的博客 6万+

遗传算法解决0-1背包问题

一:问题描述          给定n种物品,物品i(1≤i≥n)的体积为wi,价值为vi,将这n种物品放入容量为C的背包之中。在放入背包的物品总体积小于C的情况下,求放入背包物品的最大价值。   二:基本实现原理          1:编码                             问题可以表示为一个n位的二进制码,第i位表示物品i,数值为0表示物品没有选中,1表示选中物

lonerdai的专栏 1万+

算法学习3——0-1背包问题的多算法求解

问题概览:给定n种物品和一个背包。物品i的重量是Wi,其价值为Vi,背包最大承载重量为C。物品是不可分割的,应如何选择装入背包的物品,使得装入背包中物品的总价值最大。问题的最终目标:在严格遵循背包最大承载重量C的限制条件下,我们需要挑选决定哪些物品被装入背包中,确保所选择的这些物品的总价值能够达到最大化。问题的约束条件:背包最大承载重量C、物品不可分割、每个物品仅能被选择一次(0-1选择)。。

Usernames_007的博客 2424

python算法练习——贪心算法解决0-1背包问题

目录贪心算法与0-1背包问题贪心算法0-1背包问题解决策略算法实现初始化函数三种策略贪心算法比较函数主函数脚本文件运行结语致谢 贪心算法与0-1背包问题 用贪心算法解决0-1背包问题是算法界较为经典的一个问题,笔者尝试用一个python脚本,实现对输入的问题数据生成相应的最优结果。 贪心算法 贪心算法(greedy algorithm),又称贪婪法,是寻找最优解问题的常用方法。这种方法一般将求解过...

Xavier 9270

算法导论【近似算法】—0-1背包问题的近似算法

若对于每一个固定的ϵ0ϵ > 0ϵ0,算法 A 的运行时间以实例III的规模的多项式为上界,则称 A 是一个多项时间近似方案。在 PTAS 的基础上,进一步要求算法 A 的运行时间以实例III的规模和1ϵ1 / ϵ1/ϵ的多项式为上界,则称 A 是一个完全多项时间近似方案。FPTAS 被认为是最值得研究的近似算法,仅有极少数的 NP-hard 问题存在 FPTAS。

我们都是被分成两半的人,一边热爱生活,一边憎恨生活。面对生活,我们总是在矛盾的两端摇摆,在反复的矛盾和犹豫中,一边踉跄前行,一边重振旗鼓。我渴望改变,渴望变得更好,渴望找到出口……就像一个溺水人的挣扎,就像一个救生圈。我是一个矛盾集合体,想要变得快乐,但是 5067

遗传算法求解0/1背包问题

遗传算法(genetic algorithm,GA)是计算数学中用于解决最优化问题的搜索算法,是进化算法的一种。进化算法最初是借鉴了达尔文进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择以及杂交等。遗传算法通常实现方式为一种计算机模拟。对于一个最优化问题,一定数量的候选解(称为个体)可抽象表示为染色体,使种群向更好的解进化。传统上,解用二进制表示(即0和1的串),但也可以用其他表

糊涂程序员的专栏 1万+

0-1背包问题的多种算法设计与分析

0-1背包问题的多种算法设计与分析 0-1背包问题描述:给定一组共n个物品,每种物品都有自己的重量wi(i=1~n)和价值vi(i=1~n),在限定的总重量(背包的容量C)内,如何选择才能使得选择物品的总价值之和最高。选择最优的物品子集放置于给定背包中,最优子集对应n元解向量(x1,…xn), xi∈{0或1},因此命名为0-1背包问题。 输入:为方便这种大规模输入数据的调试,采用文件输入,标

wspxxy的专栏 5565

深入解析SSD报错“READ FPDMA QUEUED”:从诊断到修复全流程

本文深入解析了SSD报错“READ FPDMA QUEUED”的含义、成因与全流程解决方案。该错误通常指示硬盘硬件或健康状态问题。文章详细介绍了如何通过系统日志定位错误、解读关键的S.M.A.R.T.健康报告(重点关注重分配扇区计数等指标),并逐步进行硬件排查(如更换SATA数据线)、软件修复与数据抢救,最终指导用户根据诊断结果做出维修或更换SSD的决策。

weixin_29233333的博客 399

算法实验 0-1背包问题

实验三 算法综合实验 0-1背包问题 一、问题描述 1.给定n种物品和一个背包。物品i的重量是w[i),其价值为v[i],背包容量为c,应如何选择装入背包中的物品,使得装入背包中物品的总价值最大。 2. 在选择装入背包的物品时,对每种物品i只有两种选择,即装入背包或不装入背包。 不能将物品i装入背包多次,也不能只装入部分的物品i。 二、问题规模 1.物品数目: n=? //可以任意输入物品数目 2...

weixin_43914278的博客 3566

Excel数据清洗实战:8个必学函数搞定90%的脏数据问题(附案例)

本文通过一个完整的销售数据清洗案例,详细讲解了如何组合使用TRIM、CLEAN、SUBSTITUTE等8个核心Excel函数,构建自动化清洗流水线,高效解决日常办公中90%的脏数据问题,从而将时间留给更有价值的分析工作。

weixin_29215391的博客 583

蚁群算法 解决 0-1背包问题

蚁群算法实现0-1背包问题实验报告 【实验内容】 用蚁群算法求解0-1背包问题。 【实验环境】 Microsoft Visual C++ 6.0 【基本理论】 蚁群算法是对自然界蚂蚁的觅食寻径方式进行模似而得出的一种仿生算法。先简要介绍一下蚂蚁搜寻食物的具体过程。研究表明:蚁群在觅食途中,会在所经过路径留下一种挥发性分泌物—信息素(pheromone) ,并能感知其存在和强度,朝着信息素浓度高的方向移动。与此同时释放出与路径长度有关的...

软件工程小施同学 的专栏 4166

3、Tone Mapping色调映射(Advanced High Dynamic Range Imaging )

3、Tone Mapping色调映射(Advanced High Dynamic Range Imaging) 如今,大多数可用的显示设备无法本地显示HDR内容。 入门级显示器的对比度仅为200:1。 尽管高端液晶电视具有更高的对比度,但平均对比度约为10,000:1,但通常每个色彩通道的离散度为8位,很少为10位。 这意味着色调限制为255。在过去的二十年中,研究人员花费了大量时间和精力来压缩HDR图像和视频的范围,以便可以在LDR显示器上更“自然”地看到数据。 图3.1 色调映射和真实场景之间.

ISP行业的忠实粉丝 1866

零基础教你学RDMA驱动开发--第8篇:队列对(QP)、完成队列(CQ)与工作请求(WR)机制剖析

本文深入剖析了RDMA(远程直接内存访问)中的核心机制:队列对(QP)、完成队列(CQ)和工作请求(WR)。QP作为通信端点包含发送队列(SQ)和接收队列(RQ);WR是用户提交的操作指令,转换为工作队列元素(WQE)后由网卡异步执行;CQ则提供完成通知机制。文章详细介绍了三者的协作原理,包括QP状态机、WR提交方式、CQ轮询机制,以及关键的信号控制技术(Signaled Mode)来优化性能。同时对比了SEND/RECV和RDMA WRITE两种模式的差异,提供了调试技巧和最佳实践。这些机制共同构成了RD

amy_mhd的博客 157

【0-1背包】二进制灰狼算法解决0-1背包问题【Matlab】

一、0-1背包问题 1、问题描述 背包问题早在 1978 年由 M. Ralph 和 H. Martin 提出,是一种组合优化类的 NP(Non-deterministic Polynomial)难解问题,简单来说,就是解决如何将有限的空间更高效地利用起来,即将不同价值和体积的物品装入背包中,从而使背包所载物品价值最大的问题。在包括 0-1 背包问题、完全背包问题及多重背包问题的三类背包问题中,0-1 背包问题自提出就受到众多学者的广泛关注。 对于 0-1 背包问题的解法,就其计算复杂度来看,可以大致分为三

weixin_43945051的博客 3153

【华为OD机试】2024年真题C卷(python)-API集群负载统计

【华为OD机试】-API集群负载统计-【华为OD机试】-API集群负载统计:某个产品的 restful API 集合部署在服务器集群的多个节点上,近期对客户端访问日志进行了采集,需要统计各个API的访问频次,根据热点信息在服务器节点之间做负载均衡,现在需要实现热点信息统计查询功能。 restful API 是由多个层级构成,层级之间使用/连接,如 A/B/C/D 这个地址,A属于第一级,B属于第二级,C属于第三级,D属于第四级。 现在负载均衡模块需要知道给定层级上某个名字出现的频次,未出现过用0

u014481728的博客 1495
上一篇: Android 作业:简单计算器实现
Coder_xh
博客等级 码龄9年 15粉丝 61原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值