背包问题BP

背包问题

文章目录

一、问题描述

01背包问题:给定n种(每种1个,也就是n个)物品和一个背包。物品的重量是wi,其价值为vi,背包的容量(重量)为c。应如何选择背包中的物品,使得不超过背包容量且总价值最大。

在选择背包的物品时,对每种物品i只有两种选择,即装入背包1和不装如背包0,不能将物品装入背包多次,也不能只装一部分(商品不可分割)

二、本质

动态规划,记忆化搜索表

三、思路

3.1 01背包

3.1.1 方法
  • 枚举->共有 2 n 2^n 2n种组合(暴力)
  • 搜索( D F S / B F S DFS/BFS DFS/BFS)会超时
  • 动态规划:本质就是对搜索记忆化,只需考虑每个物品要不要装入背包即可
3.1.2 代码
cpp 复制代码
// dp[i][j] = x  从前i个物品任选若干,装入容量为j的背包的最大价值x
// 最终状态dp[n][m]    n个(也是n种)物品,m的容量(重量)
// 结果只有两种:放/不放
// 状态转移公式
dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]); 
// 注解:算dp[i][j],默认dp[i][j]之前的值已经算出,从1~i个物品中选,第i个物品选/不选,背包只从1~i-1个物品中任选,装入到容量为j的价值已经算出
// 前提:j>=w[i]

// 初始状态
// 一个物品都不选
dp[0][j]=0;
// 背包容量为0
dp[i][0]=0;

// 直接把dp数组全部初始化为0
for(int i=1;i<=n;i++)		// 枚举物品,应从1开始,是0也没意义,价值也是0
{
    for(int j=1;j<=m;j++)	// 枚举书包的容量,应从1开始,是0也没意义
    {
        if(j>=w[i])	dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
        // 防止越界
        else	dp[i][j]=dp[i-1][j];// 放不进去,只能选不放
    }
}
// 要么放不进去,干脆不放了。要么能放进去,选择放/不放,看哪个价值不大
3.1.3 模拟

注:求值时只需看上一行即可->可优化空间->降维优化

3.1.4 优化

​ 二维->一维(滚动数组)

cpp 复制代码
// 状态转移公式
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
// 初始状态
dp[j]=0;
// 答案
dp[m];

for(int i=1;i<=n;i++)
{
    for(int j=m;j>=w[i];j--)	// 比w[i]小的容积不用枚举了
    {
        // j>=w[i]防止越界
        dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    }
}
// 试问为什么j要倒着枚举?
// 在算后面的值时会用到前面的值,如果正着的话会导致前面的值被更新,但是后面的值没有被更新,前面的物品会放很多次(恰好这为完全背包提供了思路)

3.2 完全背包

3.2.1 问题描述

给n种物品,每种物品有无限多个,放入容量为m的背包中(可以重复放入同一种物品),如何使背包的价值最大。

3.2.2 思路

01背包时有个易错点,会放很多次,但是在完全背包中,刚好可以达到降维的目的(三维->二维)

3.2.3 代码
cpp 复制代码
// 没有降维的
dp[i][j]=max(dp[i-1][j],dp[i-1][j-k*w[i]]+k*v[i]);
// 降维后的
for(int i=1;i<=n;i++)
{
    for(int j=w[i];j<=m;j++)		// 从有一个开始枚举
    {
        // j>=w[i]防止越界
        dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    }
}

四、难点

题目本身不难,但是会加情景,情景中的变量和背包中的变量是否一致是需要考虑的

五、题目

5.1 洛谷

  • P1616 疯狂的采药
  • P1048 NOIP 2005 普及组 采药

四、难点

题目本身不难,但是会加情景,情景中的变量和背包中的变量是否一致是需要考虑的

五、题目

5.1 洛谷

  • P1616 疯狂的采药
  • P1048 NOIP 2005 普及组 采药
相关推荐
林浩杨_12 分钟前
SIGIR 2026|南京大学:Video-GAR:“通过生成 Query 来验证视频语义理解”的生成增强范式
论文阅读·人工智能·算法
君顾113 分钟前
西安 24 小时自助健身房系统开发实战指南
java·开发语言·健身房
Elsa️74641 分钟前
算法一周刷题总结
c++·算法
风合星语1 小时前
2026 机器人工程实例(五):让 Allegro Hand 在 MuJoCo 中完成接触抓取——抓取状态机、稳定抬升与受控释放
c++·python·机器人·仿真
小羊没烦恼!1 小时前
Memory 记忆设计讨论:Agent Memory 的数据模型可以怎么设计
java·开发语言·前端·c++·c#
小小程序猴11 小时前
深圳乘路资讯AI培训怎么样?课程靠谱吗?——一套课程可信度评估模型与实证分析
人工智能·算法
云上先途1 小时前
标签化服务适合哪些人?常见适用场景一次讲清
大数据·人工智能·算法·音视频
程序猿编码1 小时前
两张 3090 扛 27B:Qwen3.8-27B 大模型 DFlash2 加速版生产级落地
开发语言·gpt·深度学习·神经网络·大模型·qwen
welfare9621 小时前
新号别搞:内存管理+模板初阶+STL简介
开发语言·c++
彧azz1 小时前
DFS与BFS:图遍历的两大核心算法
数据结构·学习·算法·深度优先·广度优先