动态规划二(Dynamic Programming )

本文详细解析了背包问题的动态规划解决方法,通过一个具体案例,展示了如何通过构建表格来找出在不同承重下,背包所能容纳的最大价值的物品组合。文章提供了JAVA代码实现,帮助读者理解动态规划在实际问题中的应用。

动态规划一


2.背包问题

给几个物品,物品有不同的重量和价格。一个背包有自己的限重,不能将所有的物品都装进背包,则怎么搭配才能用这个背包装进最多价值的物品,给出背包能带来的最大价值?

以下表格为例:

物品重量价值/美元
1212
2110
3320
4215

背包承重为5,则怎么选择可以获得最大价值的组合?

做背包问题只要填好下面的这个表格即可。
先来看一些这个表格:
在这里插入图片描述
首先1表示给定的承重。承重从1开始,一直给到5,即背包的最大承重。
红框2给出了所有物品的重量和价值列表。

由动态规划一中的规律可以发现,动态规划会给出所有过程中的最优解,所以背包问题也会从背包承重为1开始计算,计算从最大承重为1的最优解一直解到最大承重为5的最优解。上面红框1就是承重从1开始增加,一直增加到5。
红框3表示选择范围为空时(就是所有物品都不能选时),能获得的最大价值为0

下面开始填表:
在这里插入图片描述
红框中的第一位是0,表示:
当背包承重为0,可选物品只有1号时,背包能选出的最大价值为0(因为只能选物品1,但是背包的承重又装不了1号物品)
红框中的第二位是0,情况一样;
红框中的第三位是12,表示:
当背包承重为2,可选物品只有1号时,背包能选出的最大价值是12(就是刚好装进物品1);
红框第4、5、6位都是12,表示:
当背包的承重是4、5、6时,虽然被很重,但是只有物品一可以选,所以能选出的最大价值仍然是12.


开始填第二排:
在这里插入图片描述
从第二排1号框为例,开始介绍一下填表格普遍情况:
对于表格中的任意一个框,其数值F[i][j]为:

F[i][j]=max(F[i-1][j],value[i]+F[i-1][j-weight[i]])

其中F[i-1][j]就是红框2,F[i-1][j-weight[i]]就是红框3
可以看出,表格中的一个数值要么是上一排,它正上方那格数值;
要么是上一排,第[j-weight[i]]个数值+value[i].其中j表示当前给定的背包承重,此处是2,weight[i]表示当前物品的重量,此处是1,value[i]表示当前物品的价值,此处是10

这个表达式的意义就是,给定了一个承重j之后,对于第i个物品我有两个选择
选择这个物品:
如果我选择了这个物品,我的背包的剩余承重j-weight[i],同时我剩余的可选物品是物品1–物品i-1,这样获得的价值在表格中就是红框3
不选择这个物品:
如果我不选择当前的这个物品i,我选择的结果和【给定承重为j,物品选择范围是(1—i-1)】这个条件下的结果一样,最终的价值就是红框2


根据这个规律可以填出表格中所有的值:

物品号weight,value012345
000000
12,120012121212
21,1001012222222
33,2001012223032
42,1501015253037

可以看出,这个表格其实求出了当背包承重为0–5,可选物品从0–4时,所有最优解的情况

JAVA描述:

public class DPpackage {

	public static void main(String[] args) {
		int items[][]= {
				{3,25},
				{2,20},
				{1,15},
				{4,40},
				{5,50}
		};
		int i,j;
	int F[][]=new int[items.length+1][7];
	//第一排全是0
	for(i=0;i<7;i++) 
		F[0][i]=0;
	
	for(i=1;i<items.length+1;i++) {
		F[i][0]=0; //第一列全是0
		for(j=1;j<7;j++) {
			if(j>=items[i-1][0]) {
			F[i][j]=Math.max(F[i-1][j], F[i-1][j-items[i-1][0]]+items[i-1][1]);
		}
			else F[i][j]=F[i-1][j];
		}
	}
	System.out.println(F[items.length][6]);
	}
}

先看效果: https://renmaiwang.cn/s/jkhfz Hue系列产品将具备高度的个性化定制能力,并且借助内置红、蓝、绿三原色LED的灯泡,能够混合生成1600万种不同色彩的灯光。 整个操作流程完全由安装于iPhone上的应用程序进行管理。 这一创新举措为智能照明控制领域带来了新的启示,国内相关领域的从业者也积极投身于相关研究。 鉴于Hue产品采用WiFi无线连接方式,而国内WiFi网络尚未全面覆盖,本研究选择应用更为普及的蓝牙技术,通过手机蓝牙与单片机进行数据交互,进而产生可调节占空比的PWM信号,以此来控制LED驱动电路,实现LED的调光功能以及DIY调色方案。 本文重点阐述了一种基于手机蓝牙通信的LED灯设计方案,该方案受到飞利浦Hue智能灯泡的启发,但考虑到国内WiFi网络的覆盖限制,故而选用更为通用的蓝牙技术。 以下为相关技术细节的详尽介绍:1. **智能照明控制系统**:智能照明控制系统允许用户借助手机应用程序实现远程控制照明设备,提供个性化的调光及色彩调整功能。 飞利浦Hue作为行业领先者,通过红、蓝、绿三原色LED的混合,能够呈现1600万种颜色,实现了全面的定制化体验。 2. **蓝牙通信技术**:蓝牙技术是一种低成本、短距离的无线传输方案,工作于2.4GHz ISM频段,具备即插即用和强抗干扰能力。 蓝牙协议栈由硬件层和软件层构成,提供通用访问Profile、服务发现应用Profile以及串口Profiles等丰富功能,确保不同设备间的良好互操作性。 3. **脉冲宽度调制调光**:脉冲宽度调制(PWM)是一种高效能的调光方式,通过调节脉冲宽度来控制LED的亮度。 当PWM频率超过200Hz时,人眼无法察觉明显的闪烁现象。 占空比指的...
动态规划Dynamic Programming,简称 DP)是一种用于解决**具有重叠子问题**和**最优子结构**性质的复杂问题的算法设计技术。它通过将原问题分解为若干子问题,并保存子问题的解以避免重复计算,从而高效求解。 --- ### 回答问题:什么是动态规划? #### ✅ 定义: 动态规划是一种**分治+记忆化**的算法思想,适用于可以分解为重复出现的子问题、且整体最优解包含局部最优解的问题。 核心思想是: > **“记住已经算过的结果,下次直接用”** 这与单纯的递归不同,因为普通递归会反复计算相同的子问题;而动态规划通过**自底向上**或**带记忆化的自顶向下**方式,确保每个子问题只计算一次。 --- ### 动态规划的两个关键特征: 1. **最优子结构(Optimal Substructure)** - 一个问题的最优解包含其子问题的最优解。 - 例如:从 A 到 C 的最短路径经过 B,则从 A 到 B 的那一段也必须是最短路径。 2. **重叠子问题(Overlapping Subproblems)** - 在递归求解过程中,某些子问题被多次重复计算。 - 动态规划通过**记忆化**(缓存结果)来避免重复计算。 --- ### 典型例子:斐波那契数列 斐波那契定义: $$ F(0) = 0,\quad F(1) = 1,\quad F(n) = F(n-1) + F(n-2) $$ #### 普通递归(效率低): ```c int fib(int n) { if (n <= 1) return n; return fib(n-1) + fib(n-2); } ``` 时间复杂度:$O(2^n)$ —— 大量重复计算(如 `fib(3)` 被算很多次) #### 动态规划优化(记忆化或递推): ##### 方法一:记忆化搜索(自顶向下) ```c #include <stdio.h> int memo[100]; int fib(int n) { if (n <= 1) return n; if (memo[n] != 0) return memo[n]; memo[n] = fib(n-1) + fib(n-2); return memo[n]; } ``` ##### 方法:递推法(自底向上,标准 DP) ```c int dp[100]; dp[0] = 0; dp[1] = 1; for (int i = 2; i <= n; i++) { dp[i] = dp[i-1] + dp[i-2]; } // dp[n] 即为结果 ``` 时间复杂度降为 $O(n)$,空间 $O(n)$ --- ### 动态规划的基本步骤: 1. **定义状态** 明确 `dp[i]` 或 `dp[i][j]` 表示什么含义(如最大和、最少步数等) 2. **状态转移方程** 找出当前状态如何由之前的状态推导出来 3. **初始化** 设置初始条件(如 `dp[0] = 0`) 4. **遍历顺序** 确保在计算 `dp[i]` 时,所有依赖的状态都已计算 5. **返回结果** 输出最终状态值(如 `dp[n]` 或 `dp[N][N]`) --- ### 常见类型举例: | 类型 | 特点 | 示例 | |------------|------|-------| | 线性DP | 状态在线性序列上转移 | 最长上升子序列、数字三角形 | | 区间DP | 对区间 `[i,j]` 进行操作 | 石子合并 | | 背包DP | 选择物品使价值最大 | 01背包、完全背包 | | 树形DP | 在树结构上做DP | 树的最大独立集 | | 状压DP | 状态用进制压缩表示 | TSP旅行商问题 | | 双线程DP | 同时处理两条路径 | 方格取数 | --- ### 总结: 动态规划不是一种具体的函数或语法结构,而是一种**解决问题的思想方法**。它的名字听起来很高深,但本质就是: > **把做过的事记下来,下次就不用重做** 就像你走迷宫时画地图,下次就不会再走死路。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值