01背包与完全背包详解

C++ 算法篇 动态规划----背包之一 01背包 一、01背包 题目:有 N 件物品和一个容量为 V 的背包。第 i 件物品的费用是 w[i],价值是 p[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 例,有3个物品,背包容量为10,如下: 二维解法: #include<bits/stdc++.h> using namespace std; int f[50][220]={... 阅读详情

背包问题


Image

只需要知道0-1背包和完全背包问题就完全足够了

0-1背包有以下的特点

  • 有限个物体(有重量和价值),每个物体只有一个
  • 每个物体你都可以任选,可选也可以不选
  • 有限制(上限或者下限)而且这个限制不能太

Image

dp定义

对于背包问题,有一种写法, 是使用二维数组,即dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。

关于背包的两个关键点

  • 第一怎么01背包降维的时候要反序遍历
  • 第二为什么完全背包问题的时候组合的时候先遍历物品,后遍历背包容量

01背包

接下来来详细解答这两个关键:

以下面的例子为例

假设你是一个小偷,背着一个可装下4磅东西的背包,你可以偷窃的物品如下:

img

为了让偷窃的商品价值最高,你该选择哪些商品?

这就是典型的背包问题
物品也就是nums
背包容量也就是 target
第一种解法: 定义二维dp数组
dp[i][j]: 表示在前i个物品中能放进j容量能有多少种方法
也就是说每一物体只有两种选择为正数或者负数

对于01背包问题先遍历物品和先遍历背包都是一样的只是先遍历物品更好理解

二维

先遍历物品
// weight数组的大小 就是物品个数
for(int i = 1; i < weight.size(); i++) { // 遍历物品
    for(int j = 0; j <= bagWeight; j++) { // 遍历背包容量 
        if (j < weight[i]) dp[i][j] = dp[i - 1][j]; // 这个是为了展现dp数组里元素的变化
        else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
        
    }
}
先遍历背包
// weight数组的大小 就是物品个数
for(int j = 0; j <= bagWeight; j++) { // 遍历背包容量
    for(int i = 1; i < weight.size(); i++) { // 遍历物品
        if (j < weight[i]) dp[i][j] = dp[i - 1][j];
        else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
    }
}

一维(倒着遍历防止被重复放入,详解看图)

  for(int i = 0; i < weight.size(); i++) { // 遍历物品
        for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量
            dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
        }
    }

参考链接

完全背包

完全背包的特点就是物品有无限个想怎么拿就怎么拿,所以对于纯完全背包问题先遍历背包和先遍历物品是一样的,但是如果变化那么区别就在于我们的遍历顺序

什么是完全背包问题

有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。

注意这里说的是,求解放入背包的物品价值总和最大,也就是说你这物品的放入是有序还是无序我都可以的,不管你怎么放入,这个是完全背包的一个关键点

所以在这里纯完全背包问题就是可以先遍历物品或者先遍历背包都是可以的。

279. 完全平方数

难度中等880

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。

给你一个整数 n ,返回和为 n 的完全平方数的 最少数量 。

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

示例 1:

输入:n = 12
输出:3 
解释:12 = 4 + 4 + 4

示例 2:

输入:n = 13
输出:2
解释:13 = 4 + 9
先遍历物品后遍历背包
class Solution {
public:
    int numSquares(int n) {
        // 首先这就是这个纯完全背包问题,也就是说物体是小于n的所有完全平方数,
        // 背包就是n,至于物品是否的有序或者无序放入就无所谓了,你随便放

        // 所以先遍历背包还是先遍历物品都是可以的

        /* 
            这里先遍历物品
         */

         // 先求符合条件的完全平方数
         vector<int> data;
         for(int i=1;i<=n;i++) {
             if(i*i<=n) {
                 data.push_back(i*i);
             } else {
                 break;
             }
         }


         // 定义dp
         vector<int> dp(n+1,0);
        // 初始化
        for(int i=1;i<=n;i++) {
            if(i%data[0]==0) {
                dp[i]=i/data[0];
            }
        }

         for(int i=1;i<data.size();i++) {  // 先遍历物品
             for(int j=data[i] ; j<=n; j++ ) {  // 后遍历容量
                 dp[j] = min(dp[j],dp[j-data[i]]+1);
             }
         }

         return dp[n];

    }
};

解法2

public:
    int numSquares(int n) {
        vector<int> dp(n + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 0; i <= n; i++) { // 遍历背包
            for (int j = 1; j * j <= i; j++) { // 遍历物品
                dp[i] = min(dp[i - j * j] + 1, dp[i]);
            }
        }
        return dp[n];
    }
};

这里dp[0]=0的含义就和上面的不一样,,这里dp[0]代表的是没有物品的时候,各个容量所能放的最大价值,其实也是通过二维状态压缩过来的

先遍历背包后遍历物体
class Solution {
public:
    int numSquares(int n) {
        // 首先这就是这个纯完全背包问题,也就是说物体是小于n的所有完全平方数,
        // 背包就是n,至于物品是否的有序或者无序放入就无所谓了,你随便放

        // 所以先遍历背包还是先遍历物品都是可以的

        /* 
            这里先遍历背包
         */

         // 先求符合条件的完全平方数
         vector<int> data;
         for(int i=1;i<=n;i++) {
             if(i*i<=n) {
                 data.push_back(i*i);
             } else {
                 break;
             }
         }


         // 定义dp
         vector<int> dp(n+1,INT_MAX);
        // 初始化
        dp[0]=0;
        // 代表容量为0的时候个数为0

        for(int i=0;i<=n;i++) { // 先遍历背包,不用初始化,因为背包容量为0,肯定放不下
            for(int j=0;j<data.size();j++) {
               if(i>=data[j]) {
                  dp[i] = min(dp[i],dp[i-data[j]]+1);
               }
            }
        }

         return dp[n];

    }
};
状态压缩过程

要考虑插入顺序的完全背包问题

博客地址

总结

总结

01背包问题和完全背包问题 01背包 01背包字面意思来看0就是不拿,1就是拿,且每次只能拿一个物品放入背包。 开二维数组的状态方程: 此情景为往固定容量的背包里装物品,使包内物品为最大价值 实际上就是在每个物品的基础上,遍历所有可能的背包空间,如果放得下去就比较放与不放对价值的影响 一维数组的状态方程: ... 阅读详情

相关推荐

01背包——优化详解!!!(滚动数组、一维优化)

可以看出,dp[i,j]只依赖与自己和i-1,而滚动数组就是把i给变成2,反复用0、1来进行dp,上一轮的值还是可以找到。原来空间复杂度:O(NV) 滚动数组优化后空间复杂度:O(2*N)dp[i,j]:1~i个物品组成重量

qq_60466872的博客 1816

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

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

冷兮雪的博客 3万+

面试篇 - LoRA(Low-Rank Adaptation) 原理

输出示例:trainable params: 262,144 || all params: 6,742,016,000 || trainable%: 0.0039。论文实验显示:零初始化 BB 可使初始损失与预训练模型相差不足0.1%,而非零初始化可能差50%+。若初始 ΔW≠0,模型可能立即偏离预训练学到的知识(如GPT-3突然忘记如何造句)。:如同汽车改装,先保持原厂配置(W),再逐步加装新部件(ΔW),避免直接飙车失控。:大模型的权重变化矩阵 ΔWΔW 通常是低秩的(少数主成分主导变化)。

qq_60245590的博客 1152

动态规划背包问题之01背包详解

动态规划背包问题之01背包详解

晨的博客 5万+

【四旋翼】pixhawk2.4.8-地面站配置-APM固件-四旋翼从装机到试飞

因为MP版本和APM版本的适配问题,真的真的是很大一个坑。最好先走别人走过的路,走通了再去自由发挥,不然白白浪费时间。下面提供我试飞成功过的版本。下面提供任意版本固件和地面站的下载方法。

xifan的博客 3万+

WangEditor 5.0版本dangerouslyInsertHtml方法的正确使用方式

WangEditor 5.0版本dangerouslyInsertHtml方法的正确使用方式

yang1067155909的专栏 4291

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

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

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

华为OD机试双机位A卷 - 小明减肥 (C++ & Python & JAVA & JS & GO)

华为OD机试2025双机位A卷 小明减肥,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解

qq_45776114的博客 707

背包问题详解:01背包、完全背包、多重背包

参考链接: http://www.cnblogs.com/fengty90/p/3768845.html http://blog.youkuaiyun.com/mu399/article/details/7722810 http://blog.youkuaiyun.com/xiaowei_cqu/article/details/8191808 http://blog.youkuaiyun.com/insistgogo/article/

na_beginning的专栏 11万+

SAP特殊库存全解析:供应商寄售、客户寄售、分包与项目库存说明

客户寄售库存(Customer Consignment)是企业将物料存放于客户处,客户实际领用后才确认销售收入。这种模式能缩短交货周期、提高客户满意度,但需严格跟踪寄售库存的数量与状态。

我小时候很黑的博客 822

CAN(2)-GD32

GD32中CAN的特征。

小柚子的博客 553

【算法】背包问题详解:从01背包到完全背包

背包问题是动态规划的经典入门题型,主要分为01背包(每个物品只有一个)和完全背包(每种物品有无限件)。本文从零开始,详细推导二维DP的状态转移方程,并深入讲解一维空间优化的核心原理。通过对比两者的遍历顺序差异——01背包逆序、完全背包正序,帮助你理解背后的逻辑:防止重复选取与允许重复选取。配合示例推导和代码实现,一文打通背包问题的基础关卡。

2301_81073406的博客 1151

GB 47955—2026 L2组合驾驶辅助强制国标全解、合规方案与工程代码落地

GB 47955—2026 L2辅助驾驶国标合规工程代码# 运行环境:Python3.8+,适配车载仿真、台架测试、算法验证场景# 依赖安装:pip install numpy dataclasses tqdm struct time json# ===================== 国标强制时序参数(完全对标GB 47955—2026) =====================HAND_OFF_FIRST_WARN = 5.0 # 手部脱离5s触发一级预警。

lin_xiu的博客 299

01背包,完全背包,混合背包详解

01背包,完全背包,多重背包详解 01背包 01背包就是给n个物体,每个物体都有代价w[i] 和 价值 v[i]; 给定一个容量为t的背包,每个物体只能选一次装入背包,所能得到的最大价值是多少 动态规划就是找状态转移方程, dp[ i ] [ j ]=max ( dp [ i - 1 ] [ j ] , dp [ i -1 ] [ j - w [ i ] ]+ v [ i ] ) dp[ i ] [ j ] 表示从前 i 个物品中挑选物品放入容量为 j 的背包可以获得的最大价值。 就是在当前状态有两种选择

远坂凛大小姐 509

风控域——决策引擎系统设计

本文详细介绍了风控决策引擎系统的设计与应用。决策引擎系统是一种智能化工具,可自动化、数据驱动地辅助或替代人工决策,广泛应用于金融、医疗、营销、风控等领域。文章阐述了决策引擎的核心功能,包括自动化决策、动态规则管理、实时处理和模型集成,以及系统组成,涵盖数据输入层、规则引擎和模型服务层。此外,还探讨了决策引擎的典型应用场景、技术架构、组件设计,以及风控决策引擎系统的技术方案、设计难点和重点。

庄小焱 3320

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

01背包、完全背包、多重背包详解

目录 一、01背包问题 二、完全背包问题 三、多重背包 一、01背包问题 问题: 有n件物品和一个容量是m的背包。第i件物品的体积是vi,价值是wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。 解答: 问题中每个物品只有选与不选两种状态。 动态规划的状态转移方程:dp[i][j] = max(dp[i-1][j], dp[i][j-vi]+wi) , d[i][j]表示只看前i个物品且总体积是j时,最大的价值。 //v是物品的体积,w是价

qq_22228095的博客 2706

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

背包问题分析代码详解【01背包+完全背包+多重背包】

由于f[i,j-v]中多了一项f[i-1,j-(s+1)v]+sw,所以f[i-1,j-v]+w,f[i-1,j-2v]+2w,f[i-1,j-3v]+3w,…f(i,j−v)=max(f[i,j−v],f[i,j−2v]+w,⋯,f[i,j−(s+1)v]+sw)(滑动窗口已满)f(i,r+(s+1)v)=max(f[i,r+(s+1)v],f[i,r+sv]+w,⋯,f[i,r+v]+sw)(滑动窗口已满)简言之,在j........................

weixin_61907955的博客 4295

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

背包之01背包、完全背包、多重背包详解

首先说下动态规划,动态规划这东西就和递归一样,只能找局部关系,若想全部列出来,是很难的,比如汉诺塔。你可以说先把除最后一层的其他所有层都移动到2,再把最后一层移动到3,最后再把其余的从2移动到3,这是一个直观的关系,但是想列举出来是很难的,也许当层数n=3时还可以模拟下,再大一些就不可能了,所以,诸如递归,动态规划之类的,不能细想,只能找局部关系。 图1.汉诺塔图片 (引至杭电课件:DP最关键的就是状态,在DP时用到的数组时,也就是存储的每个状态的最优值,也就是记忆化搜索) 要了解背包,首先得清楚

Augusdi的专栏 1500

【详解】01背包 | 完全背包(原理+例题)

详解01背包和完全背包

每篇博客都不是最终版,都会随着我的学习更新 3324

01背包问题和完全背包问题难点详解

本文主要是用于复习,了解动态规划但是经常记不住要如何使用,以及为社么要这样用,不太适合刚学习动态规划的人。

weixin_54398380的博客 4697

背包问题双雄:01 背包与完全背包详解(Java 实现)

dp[j]:背包容量为j时能获得的最大价值。同 01 背包,dp[j]表示容量为j时的最大价值。01 背包:倒序遍历防重复,选或不选取最值。完全背包:正序遍历允重复,同物多次算价值。

2202_75601845的博客 1235
上一篇: 全网最详细qt_ros环境搭建
下一篇: 关于完全背包的遍历形式详解
黑猫爱小鹿
博客等级 码龄8年 1万+粉丝 205原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值