动态规划--01背包问题

news/2024/10/18 19:26:31/

01背包问题

  • 背包问题
    • 题目
    • 最优解结构性质
    • 状态转移方程
      • 方程
      • 理解
    • 递归实现
      • 核心思想
      • 代码实现
      • 用例测试
    • 画表非递归实现
      • 核心思路
      • 代码实现
      • 画表展示
    • 计算哪些物品放入
      • 算法思想
      • 代码实现

背包问题

题目

0-1背包问题:给定n种物品和一背包。物品à的重量是w;,其价值为v; ,背包的容量为C。问:应该如何选择装入背包的物品,使得装入背包中物品的总价值最大?

最优解结构性质

W[n]={w1,w2,...wn};//重量数组
V[n]={v1,v2,...vn};//价值数组
X[n]={x1,x2,...xn};//结果数组

该问题可以总结为该数学公式

SUM(wi*xi)<=C 
&&
MAX(SUM(vi*xi));

在选择装入背包的物品时,对每种物品i只有两种选择,即装入背包或不装人背包。不能将物品i装入背包多次,也不能只装人部分的物品i。因此,该问题称为0-1背包问题,分析时,还是用分治策略,缩小规模,从后面砍数据,将最后一个物品去除

SUM(wi*xi)<=C-wn-1;i=1,2,..n-1;&&
MAX(SUM(vi*xi));i=1,2,..n-1;

用m[i][j]来表示当装了i个物品后,背包剩余的空间大小为j时,此时背包中物品的最大价值

注意: i不是一个点值,而是一个区域值,从 0 1 …到i

状态转移方程

方程

  • i==1时
    • m[1][j]=j>w[1]?v[1]:0
  • i>1时,考虑是否能放下,考虑放不放两种选择,
    • 放不下的话
      • m[i][j]=m[i-1][j]
    • 能放下考虑最大值
      • m[i][j]=max(m[i-1][j],m[i-1][j-w[i]]+v[i])

理解

当只有一个物品时,看能不能放下,能放下,就有价值,否则价值为0
多个物品时,看第i个物品能否放下,取决于背包的剩余容量,
**如果放不下,**价值就和i-1时一样,
**能放下,**要考虑放不放,放的话,价值增加,但是就占了空间,可能导致后面性价比高的东西放不下了,所以此时需要取最大值

不放入背包时:第i次决策后的最大价值和第i-1次决策时候的价值是一样的还是原来的那些物体,没多没少。
放入背包时:第i次决策后的价值为 第i-1次决策时候的价值 加上 当前物体的价值v[j]。物体放入背包前背包容量变为 j ,放入后,容量就会变小j-w[i],即此时价值为前一个物品放入时,剩余容量为j-w[i]时的价值

递归实现

核心思想

刚开始物品比较多,每次都依赖于前面的价值,每次都在缩小规模,等缩小到底部时,再依次回溯,得出结果

代码实现

int Knapsance(int* V, int* W, int i, int n,int j) {if (i == 1) {if (j >= W[i]) return V[i];else return 0;}else {if (j < W[i]) {return Knapsance(V, W, i - 1, n, j);}else {int v1 = Knapsance(V, W, i - 1, n, j);int v2 = Knapsance(V, W, i - 1, n, j - W[i]) + V[i];if (v1 > v2)return v1;else return v2;}}
}

用例测试

int main() {const int n = 5;const int c = 10;int W[n + 1] = { 0,2,2,6,5,4 };int V[n + 1] = { 0,6,3,5,4,6 };vector<vector<int> >m(n + 1, vector<int>(c + 1, 0));int maxv = Knapsance(V, W, n,n , c);cout << maxv;return 0;
}

输出结果为15

画表非递归实现

核心思路

从底部向上记录,根据动归表达式,自底向上记录。先初始化第一行第一列,然后根据动归表达式依次填写。
int W[n + 1] = { 0,2,2,6,5,4 };
0 1 2 3 4 5
int V[n + 1] = { 0,6,3,5,4,6 };

代码实现

int NiceKnapsance2(int* V, int* W, int n, int c, vector<vector<int> >& m) {for (int j = 1; j <= c; j++) {m[1][j] = j > W[1] ? V[1] : 0;}PrintVector(m);for (int i = 1; i<=n; i++) {for (int j = 1; j <= c; j++) {if (j < W[i]) {m[i][j] = m[i - 1][j];}else {m[i][j] = std::max(m[i - 1][j], m[i - 1][j - W[i]] + V[i]);}}PrintVector(m);}return m[n][c];
}

画表展示

在这里插入图片描述

计算哪些物品放入

算法思想

根据画的表,进行回溯,标记求解

代码实现

void Traceback(vector<vector<int>>& m, int W[], int n, int c, bool X[]) {for (int i = n; i >= 1; i--) {if (m[i][c] != m[i-1][c]) {X[i] = true;c = c - W[i];}}
}

http://www.ppmy.cn/news/63310.html

相关文章

Android studio单独导入官方例程camera-calibration

1.官方例程camera-calibration 2.将官方例程camera-calibration copy到AndroidStudioProjects项目目录下 3修改AndroidManifest.xml <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android“http://schemas.android.com/apk/res/andr…

医院智能导诊系统,医院导航解决方案

随着现代医院规模不断扩大&#xff0c;功能区域越来越细化&#xff0c;面对复杂的楼宇结构&#xff0c;集中的就诊人流&#xff0c;患者在就诊中经常会面临找不到目的地的困境&#xff0c;就诊体验变差。针对这个问题&#xff0c;一些面积和规模都比较大的医院&#xff0c;已经…

零基础入门 Stable Diffusion - 无需显卡把 AI 绘画引擎搬进家用电脑

我从小特别羡慕会画画的伙伴。他们能够将心中的想法画出来&#xff0c;而我最高水平的肖像画是丁老头。但在接触 Stable Diffusion 之后&#xff0c;我感觉自己脱胎换骨&#xff0c;给自己贴上了「会画画」的新标签。 丁老头进化旅程 Stable Diffusion 是一个「文本到图像」的…

线上问题-CPU使用频率飙升

描述 中午收到群内人员反馈环境访问速度慢。登录验证码打不开等问题。通过查看日志发现是kafka出现问题&#xff0c;无法处理消息。联系运维解决。在排查的过程中使用mobaXterm连接服务器。左下角看到CPU使用频率非常高。于是记录一下通过CPU查看程序占用情况分析问题。 过程 …

JVM(类的加载与ClassLoader、双亲委派机制)

文章目录 1. 类的生命周期2. 类的加载过程3. 类加载器&#xff08;classloader)3.1 类加载器的作用3.2 类加载器的分类(JDK8)3.3 双亲委派机制3.3.1 双亲委派机制优势 3.4 查看某个类的类加载器对象3.5 使用ClassLoader获取流 1. 类的生命周期 类在内存中完整的生命周期&#…

MapReduce框架原理

从源码的角度 :map --> sort —> copy --> sort -->reduce   sort —> copy --> sort属于shuffle InputFormat数据输入 切片与MapTask并行度决定机制 1&#xff09;问题引出 MapTask的并行度决定Map阶段的任务处理并发度&#xff0c;进而影响到整个Job的…

如何安装oracle的sample schema

首先从如下的地址选择合适的版本进行下载 https://github.com/oracle-samples/db-sample-schemas/releases 如果是rac环境&#xff0c;最好是将这个数据库停掉&#xff0c;然后只启动一个instance&#xff0c;然后再开始安装 [Tue May 09 20:26:34][377951][oraclenshqae01adm…

Vue监听属性详细讲解

文章目录 定义要监听的属性定义 watch修改监听的属性值监听数组变化监听对象变化监听计算属性变化监听事件变化监听路由变化 在 Vue 中&#xff0c;可以使用 watch/$watch 方法监听数据、计算属性、事件和路由的变化&#xff0c;从而实现数据绑定、事件监听和路由控制等功能。需…