经典算法-----01背包问题(动态规划)

news2024/12/28 3:15:39

目录

前言

01背包问题

问题描述

​编辑

动态规划

基本概念

怎么理解动态规划?

解决01背包问题

代码实现


前言

        今天我们学习一种新的算法---动态规划,这种算法思想是属于枚举的一种,下面我就通过01背包问题来说明这种算法的解决思路。

01背包问题

问题描述

现在有n个物品,它们有各自的体积和价值,然后通过一定容量capacity的背包去装这些物品,问怎么去装实现价值最大化?

图示如下: 

动态规划

基本概念

        动态规划(英语:Dynamic programming,简称 DP),是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。

        以上定义来自维基百科,看定义感觉还是有点抽象。简单来说,动态规划其实就是,给定一个问题,我们把它拆成一个个子问题,直到子问题可以直接解决。然后呢,把子问题答案保存起来,以减少重复计算。再根据子问题答案反推,得出原问题解的一种方法。

怎么理解动态规划?

        举个例子,1+1+1+1+1=?,很显然答案是5,好那我要算出6怎么去算呢?那就在5的基础上再+1就行了,这就是动态规划的表现,也就是说我前面需要一个东西来标记我前面算出来的值,然后后面要进一步去算的时候就只需要把这个值拿过来用就行了,不需要去重新算,这就是动态规划。

解决01背包问题

        当我们看到01背包问题的时候,我们可能会去一个一个列举,然后找到最优解,在列举的过程中你是否发现一些规律呢?也就是当我们列举了前面一些情况的时候,再去列举后面的其他情况就没必要去重新思考前面的东西,也就是说我们可以通过前面的直接去递推后面的即可。这就是动态规划的精髓所在。下面我就详细说明通过动态规划来解决这个问题的过程。

为了方面说明,下面定义一些量:

1、i表示第i个物品;

2、v(i)表示第i个物品的价值;

3、w(i)表示第i个物品的重量(容量);

4、V(i,j) 表示当背包容量为j的时候,能最大装下前i个物品整体的最大价值

这么来说的话,我们只需要去找到所有的V(0,0)~V(i,j) 情况即可,然后列举出来就知道最优解。

当前会发现有两种递推规律:

1如果当前容量j过于小的话,即使增加一个物品i的范围也无法装下,那么当前价值还是前i-1个物品的价值,也就是V(i,j)=V(i-1,j)

2.如果当前容量j能装下当前增加范围的物品话,即使能装下但不一定是最佳情况,那么我们要去与前面情况V(i-1,j)进行比较,也就是V(i,j)=max{V(i-1,j) , V(i,j-w(i))+v(i)}

  • j<w(i)      V(i,j)=V(i-1,j)
  • j>=w(i)     V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i)}

通过以上的规律,我们就可以去做出一张表来,i和j都从0开始,如下图所示:

然后就是填表环节,比如:i=1,j=1的时候,V(1,1)=V(1-1,1)=V(0,1)=0;当i=2,j=2的时候,V(2,2)=max{V(1,2),V(2,2-2)+v(2)},结果就是2,以此类推……

填表结果如下:

可以看,最大容纳价值就是V(4,9)=13

代码实现

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//比较二者返回最大值
int max(int a, int b) {
	return a > b ? a : b;
}

//输出结果
void print(int** table, int line, int bag_c,int* judge) {
	for (int x = 0; x < line; x++) {
		for (int y = 0; y < bag_c + 1; y++) {
			printf("%-3d ", table[x][y]);
		}
		puts("");
	}
	printf("\n当背包容量为%d的时候,最大容纳价值:%d\n", bag_c, table[line-1][bag_c]);
}

//填表操作
void build_table(int* val,int* weight,int** table,int bag_j,int line,int* judge)
{
	for (int x = 1; x < line; x++) {
		for (int j = 1; j < bag_j + 1; j++) {
			if (j < weight[x])//如果当前背包的容量无法装下多余的物品时候,那么价值还是上一个的价值
				table[x][j] = table[x - 1][j];
			else {//如果能装下,那就比较装下之后和之前的价值,取最大
				table[x][j] = max(table[x - 1][j], table[x - 1][j - weight[x]] + val[x]);
				if (table[x][j] != table[x - 1][j])
					judge[x] = table[x][j];
			}
		}
	}
}


int main() {
	int bag_j;
	printf("输入你的背包容量:");
	scanf("%d", &bag_j);
	//当前背包的价值以及对应的重量
	int value[] = { 0,2,4,3,7 };
	int weight[] = { 0,2,3,5,5 };
	
	int line = sizeof(value) / sizeof(int);//表格的行数
	int* judge = (int*)malloc(sizeof(int) * line);
	int** table = (int**)malloc(sizeof(int*) * line);
	for (int k = 0; k < line; k++) {
		table[k] = (int*)malloc(sizeof(int) * (bag_j + 1));
	}
	for (int i = 0; i < line; i++) {
		for (int j = 0; j < bag_j + 1; j++) {
			table[i][j] = 0;//表格数据初始化为0
		}
	}
	memset(judge, 0, sizeof(judge));//初始化

	build_table(value, weight, table, bag_j, line,judge);
	print(table, line, bag_j,judge);
}

结果如下:

以上就是本期的全部内容了,我们下一期再见!

分享一张壁纸:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1067432.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GEE17: 基于Theil-Sen Median斜率估计和Mann-Kendall趋势分析方法分析四川省2022年NDVI变化情况

Theil-Sen Median Mann-Kendall 1. Theil-Sen Median Mann-Kendall 原理1.1 Theil-Sen Median1.2 Mann-Kendall 2. GEE code 1. Theil-Sen Median Mann-Kendall 原理 1.1 Theil-Sen Median Theil-Sen Median方法又称为Sen斜率估计&#xff0c;是一种稳健的非参数统计的趋势…

LeakyReLU激活函数

nn.LeakyReLU 是PyTorch中的Leaky Rectified Linear Unit&#xff08;ReLU&#xff09;激活函数的实现。Leaky ReLU是一种修正线性单元&#xff0c;它在非负数部分保持线性&#xff0c;而在负数部分引入一个小的斜率&#xff08;通常是一个小的正数&#xff09;&#xff0c;以防…

JVM(八股文)

目录 一、JVM简介 二、JVM中的内存区域划分 三、JVM加载 1.类加载 1.1 加载 1.2 验证 1.3 准备 1.4 解析 1.5 初始 1.6 总结 2.双亲委派模型 四、JVM 垃圾回收&#xff08;GC&#xff09; 1.确认垃圾 1.1 引用计数 1.2 可达性分析&#xff08;Java 采用的方案&a…

BI系统有哪些?新手怎么选?

从本土化服务以及契合中国企业使用习惯等方面来看&#xff0c;建议采用国产BI系统。国内比较知名的BI工具有很多&#xff0c;比如亿信华辰BI(亿信ABI)、思迈特BI(Smartbi)、奥威BI(OurwayBISpeedBI)、帆软BI(FineBI)等。 这些BI系统在操作上都比较简单&#xff0c;比如像奥威B…

Vue中...(扩展运算符)的作用

对数组和对象而言&#xff0c;就是将运算符后面的变量里东西每一项拆下来。 &#xff08;一&#xff09;操作数组 // 1.把数组中的元素孤立起来 let iArray [1, 2, 3]; console.log(...iArray); // 打印结果 1 2 3// 2.在数组中添加元素 let iArray [1, 2, 3]; console.log…

拉取公司前端项目本地运行结果Bug频出,看我是如何一步一步成功解决的

文章目录 前端项目运行Bug记录问题背景npm install 报错问题1&#xff1a;npm install 报错ERESOLVE could not resolve问题2&#xff1a;npm install 报错 Cannot read properties of null问题3&#xff1a;node安装了npm没安装问题4&#xff1a;npm和node不兼容问题5&#xf…

新文件覆盖旧文件还能复原吗,3个方法快速恢复覆盖文件!

iPhone在解压压缩文件时&#xff0c;不小心将同名文件进行了覆盖&#xff0c;怎么撤回&#xff1f; 在使用U盘转移文档时&#xff0c;意外将同名文档进行了替换&#xff0c;怎么恢复&#xff1f; 当误将重名文件进行了替换&#xff0c;如何找回这些被覆盖的旧文件&#xff1f;…

Vue中的数据绑定

一、v-bind单向数据绑定 单向数据绑定中&#xff0c;数据只能由data流向页面。 v-bind:属性名"data变量" 或简写为 :属性名"data变量" 我们修改data中的iptvalue值&#xff0c;页面input框中的value值改变。 而我们修改input框中的value值&#xff0…

【C++初阶(二)C——C++过渡必看】

文章目录 前言一、C关键字&#x1f34e;二、命名空间&#x1f345;1.命名空间的定义&#x1f352;2.命名空间使用&#x1f353; 三、C输入&输出&#x1f351;四、缺省参数&#x1fad1;1. 缺省参数概念&#x1f349;2. 缺省参数分类&#x1f95d; 五、函数重载&#x1f965…

【Vue面试题五】说说你对Vue生命周期的理解?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;请描述下你对vue生命周期…

八、互联网技术——物联网

文章目录 一、智慧物联案例分析二、M2M技术三、数据保护综合案例分析一、智慧物联案例分析 智能物流是一种典型的物联网应用。一个物流仓储管理系统架构如下图所示: [问题1] 图中的三层功能:仓库物品识别、网络接入、物流管理中心,分别可对应到物联网基本架构中的哪一层? …

金九银十,刷完这个笔记,17K不能再少了....

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;得准备面试了&#xff0c;又不知道从何下手&#xff01;为了帮大家节约时间&#xff0c;特意准备了一份面试相关的资料&#xff0c;内容非常的全面&#xff0c;真的可以好好补一补&#xff0c;希望大家在都能拿到理想…

MybatisPlus01

MybatisPlus01 1.MybatisPlus初体验 1.1首先要引入MybatisPlus的依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency>1.2定义Mapp…

【论文极速读】EMT——评估多模态LLM中的灾难性遗忘问题

【论文极速读】EMT——评估多模态LLM中的灾难性遗忘问题 FesianXu 20231001 at Baidu Search Team 前言 论文[1]报告了多模态LLM中遇到的灾难性遗忘问题&#xff0c;并且提出了一种评估其程度的方法EMT&#xff0c;本文简要介绍&#xff0c;希望对读者有所帮助。如有谬误请见谅…

criu简单例子

CRIU&#xff08;Checkpoint/Restore In Userspace&#xff09;是运行在linux操作系统上的一个开源软件&#xff0c;其功能是在用户空间实现Checkpoint/Restore功能。 github地址如下&#xff1a;https://github.com/checkpoint-restore/criu 本人选取的版本是3.12&#xff0…

使用V-Ray for SketchUp 进行室外场景操作流程!

使用V-Ray for SketchUp 渲染时&#xff0c;可让大家轻松创建出色的渲染效果。如何使用V-Ray for SketchUp 进行室外场景操作呢&#xff1f; 对于一些新手朋友&#xff0c;可能是不知所措的&#xff0c;今天小编通过一个室外场景案例流程来给大家展示看看。 1、设置场景 可视化…

FPGA设计时序约束三、设置时钟组set_clock_groups

目录 一、背景 二、时钟间关系 2.1 时钟关系分类 2.2 时钟关系查看 三、异步时钟组 3.1 优先级 3.2 使用格式 3.3 asynchronous和exclusive 3.4 结果示例 四、参考资料 一、背景 Vivado中时序分析工具默认会分析设计中所有时钟相关的时序路径&#xff0c;除非时序约束…

Android子线程可以更新UI

目录 1 传统更新UI的七种方式1.1 new Handler()1.2 new Handler.Callback()1.3 new Handler().post(Runnable r)1.4 new Handler().postDelayed(Runnable r, long delayMillis)1.5 Activity.runOnUiThread(Runnable action)1.6 View.post(Runnable action)1.7 View.postDelayed…

科普丨如何让语言芯片保持稳定性能

一、勿长期高磁接触 虽然高质量的语音芯片的高声量范围相对较大&#xff0c;但是智能语音芯片一般分为不同情况使用&#xff0c;首先是内外不能混用&#xff0c;不仅如此在室内使用时也要防止长期的高磁接触&#xff0c;这样也会使语音芯片寿命折损。 二、定期清尘擦拭 专业…

计算机网络拓扑结构

什么是计算机网络拓扑结构&#xff1f; 计算机网络拓扑结构是指在网络中连接计算机和设备的方式或布局。它决定了如何在网络中传输数据&#xff0c;以及网络中的设备如何相互通信。不同的拓扑结构适用于不同的场景和需求&#xff0c;因此选择正确的拓扑结构对于网络性能和可用…