当前位置:网站首页>动态规划111
动态规划111
2022-06-26 19:43:00 【江江春】
基础问题
- 背包问题(带限制的取集合,求价值或种类)
- 打家劫舍
- 股票问题
- 子序列问题
基本解法
- dp数组,以及下标含义
- 递推公式
- dp数组初始化
- 遍历顺序(一维数组一层,二维数组两层)
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。
若是01背包,则从后往前,否则从前往后
- 打印数组(debug)
思路:
关键是自底向上思考
首先考虑步骤,
比如背包问题,步骤就是一个一个放入物品,怎样放入物品才是最优解。每一个物品有两步放,不放。观察全局决定放还是不放。(从头往后退看是否要放入)
再比如上台阶问题,步骤就是跨步,跨几步是最优解,每次可以跨一步或者两步。观察全局决定跨一步还是两步。(从头往后退,每次是一步最优还是两步最优)
凡是一步一步地问题,下个状态有依赖于上一个状态的问题考虑用动态规划.首先从最后一步开始,想象出最后一步到终点的状态需要哪些操作
动态规划数组的值一定是答案
背包问题(求价值问题)
究其根本是有限制与求价值的取集合。背包容量与物品重量构成限制,物品价值即为价值。
二维写法:

// 1 dp数组下标及自身含义
// dp[i][j]
//i:从0 -i号商品 j:背包容量
//ij:从0-i任取,放入j中的最大价值
// 2 递推公式
// dp[i][j]=max(dp[i-1][j],dp[i-1][j-w]+value)
// 3 dp数组初始化
//实际情况
// 4 遍历顺序
//先背包在物品
//
function bagProblem(weight,value,volume){
let count=weight.size+1
// 1 定义dp
const dp=[]
// 3 初始化dp数组
for (let j = volume; j >= weight[0]; j--) {
dp[0][j] = dp[0][j - weight[0]] + value[0];
}
// 4 遍历顺序
for(let i=1;i<weight.length;i++){
for(let j=0;j<=volume;j++){
if(j<weight[i]){
dp[i][j]=dp[i-1][j]
}else{
// 2 递推公式
dp[i][j]=max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
}
}
}
}压缩,一维写法
由上图可以得出dp[i][j]部分是由dp[i-1][j]拷贝而来,完全可以省略空间,用一维数组代替
1、dp定义
在一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]。
2、递推公式
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
此时dp[j]有两个选择,一个是取自己dp[j],一个是取dp[j - weight[i]] + value[i],指定是取最大的,毕竟是求最大价值,
3、dp数组初始化
初始化为0
4、遍历顺序
从后往前循环,每次取得状态不会和之前取得状态重合,这样每种物品就只取一次了。
对于二维dp,dp[i][j]都是通过上一层即dp[i - 1][j]计算而来,本层的dp[i][j]并不会被覆盖!
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]);
}
}
// 1 dp数组下标及自身含义
// dp[j]:容量为j时的最大价值
//j:容量
// 2 递推公式
// dp[j]=max(dp[j],dp[j-w[i]]+value)
// 这里的dp[j]其实是二维数组中上一层的复制,即上一个物品不放时的价值
// 3 dp数组初始化
//都为0
// 4 遍历顺序
//先背包在物品
// 倒序遍历背包,防止上层状态被覆盖
function bagProblem(weight,value,volume){
let count=weight.size
// 1 定义dp
const dp=[]
// 3 初始化dp数组
//
for(let i=0;i<volume;i++){
dp[i]=0
}
// 4 遍历顺序
for(let i=0;i<weight.length;i++){
// ps:大于weight,小于weight直接放不进去继承上一层状态(直接不放入)
for(let j=volume;j>=weight[i];j--){
// 2 递归公式
dp[j]=max(dp[j],dp[j-weight[i]]+value[i])
}
}
}装满背包问题
组合问题
题目链接:https://leetcode-cn.com/problems/target-sum/
难度:中等
给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。
返回可以使最终数组和为目标数 S 的所有添加符号的方法数。
限制:
left = (target + sum)/2 。
步骤
确定dp数组以及下标的含义
dp[j] 表示:填满j(包括j)这么大容积的包,有dp[i]种方法
其实也可以使用二维dp数组来求解本题,dp[i][j]:使用 下标为[0, i]的nums[i]能够凑满j(包括j)这么大容量的包,有dp[i][j]种方法。
2、递推公式
不考虑nums[i]的情况下,填满容量为j - nums[i]的背包,有dp[j - nums[i]]中方法。
那么只要搞到nums[i]的话,凑成dp[j]就有dp[j - nums[i]] 种方法。
举一个例子,nums[i] = 2:dp[3],填满背包容量为3的话,有dp[3]种方法。
那么只需要搞到一个2(nums[i]),有dp[3]方法可以凑齐容量为3的背包,相应的就有多少种方法可以凑齐容量为5的背包。
那么需要把 这些方法累加起来就可以了,dp[i] += dp[j - nums[j]
3、dp数组如何初始化
从递归公式可以看出,在初始化的时候dp[0] 一定要初始化为1,因为dp[0]是在公式中一切递推结果的起源,如果dp[0]是0的话,递归结果将都是0。
dp[0] = 1,理论上也很好解释,装满容量为0的背包,有1种方法,就是装0件物品。
dp[j]其他下标对应的数值应该初始化为0,从递归公式也可以看出,dp[j]要保证是0的初始值,才能正确的由dp[j - nums[i]]推导出来。
4、遍历顺序
01背包问题一维dp的遍历,nums放在外循环,target在内循环,且内循环倒序。
几种背包的递推公式
问能否能装满背包(或者最多装多少):dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]); ,对应题目如下:
问装满背包有几种方法:dp[j] += dp[j - nums[i]] ,对应题目如下:
问背包装满最大价值:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); ,对应题目如下:
问装满背包所有物品的最小个数:dp[j] = min(dp[j - coins[i]] + 1, dp[j]); ,对应题目如下:
打家劫舍
边栏推荐
- 问题解决:虚拟机无法复制粘贴文件
- Request method 'POST' not supported
- 好物推荐:移动端开发安全工具
- 8VC Venture Cup 2017 - Final Round C. Nikita and stack
- The king of Internet of things protocol: mqtt
- Tiktok practice ~ search page ~ scan QR code
- Preliminary analysis of serial port printing and stack for arm bare board debugging
- The goal you specified requires a project to execute but there is no POM
- When are global variables initialized before entering the main function?
- Bonne Recommandation: développer des outils de sécurité pour les terminaux mobiles
猜你喜欢

Guomingyu: Apple's AR / MR head mounted display is the most complicated product in its history and will be released in January 2023

微信小程序 uniapp 左滑 删除 带删除icon

Pinda general permission system (day 3~day 4)

mysql的充值问题

Selection of database paradigm and main code

Some cold knowledge about QT database development

刷新三观的HP-UX系统中的强指针赋值出core问题

Project practice 6: distributed transaction Seata

Create a time blocker yourself

Introduction to single chip microcomputer one-on-one learning strategy, independent development program immediately after reading
随机推荐
Micro service single sign on system (SSO)
元宇宙链游开发案例版 NFT元宇宙链游系统开发技术分析
关于Qt数据库开发的一些冷知识
Arduino UNO + DS1302利用31字节静态RAM存储数据并串口打印
好物推荐:移动端开发安全工具
Create a time blocker yourself
Record of user behavior log in SSO microservice Engineering
mongoDB的三种基础备份方法
【Kubernetes】Kubernetes 原理剖析与实战应用(更新中)
微服务架构
Unity——Mathf. Similarities and differences between atan and atan2
The successfully resolved idea cannot use the log normally after referencing Lombok's @slf4j
8VC Venture Cup 2017 - Final Round C. Nikita and stack
On the escape of inequality value
Feign远程调用
MySQL - table creation and management
What are the specific steps for opening a stock account? Is it safe to open an account online?
字符串String转换为jsonArray并解析
Some basic mistakes
C exercise. Class list plus records, display records and clear records