当前位置: 首页 > wzjs >正文

银川网站开发公司灰系网站

银川网站开发公司,灰系网站,职教集团网站建设方案,甘肃省集约化网站建设试点动态规划 背包问题(0-1 背包问题) 0-1 背包:n 个物品,每个物品只有一个 完全背包:n 种物品,每个物品有无限个 多重背包:n 种物品,每个物品个数不相同 暴力解法 场景题目类型给出表…

动态规划

背包问题(0-1 背包问题)

在这里插入图片描述

0-1 背包:n 个物品,每个物品只有一个
完全背包:n 种物品,每个物品有无限个
多重背包:n 种物品,每个物品个数不相同

暴力解法

场景题目类型给出表格,背包最大容量 n,说怎么装利益最大化

重量价值
物品0115
物品1320
物品2430

暴力解法就是穷举(回溯)当装满了背包统计价值再试试其他的,这样穷举所有可能情况,得出最佳结论

动态规划思路

Dp 数组定义

Dp 说明 dp[i][j]
[0,i] 物品种类种任取放一个物品进容量为 J 背包里所能取到的最大价值总和

递推公式确定

dp[i][j]=std::max(dp[i-1][j], dp[i-1][j-weight[i]] + value[i])
递推公式取最大值

  • 不放物品i:背包容量为j,里面不放这个物品i的最大价值是 dp[i - 1][j]
    不放物品 i,i-1 表示排除这个物品,所能获得的最大价值。
  • 放物品i:背包空出物品i的容量后,背包容量为 j - weight[i] 此时 dp[i - 1][j - weight[i]] 为背包容量为 j - weight[i] 且不放物品i的最大价值,那么 dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值
    放了物品 i,i-1 表示除了这个物品的其他物品,j-weight[i] 表示当前物品需要占据的重量
初始化 Dp 数组

根据递推公式得出要初始化上方与左方的数值,类似于上一道题的路径问题
初始化路径时上方 dp[0][j] 和左方 dp[i][0] 都要正确初始化,其他地方数值初始化没有关系
在这里插入图片描述

遍历顺序

0-1 背包问题两层 for 循环都可以遍历(先遍历物品再遍历背包)
判断是否可以正确遍历看递推公式数据来源是否稳定,先便利物品再遍历背包和先遍历背包再遍历物品
最后实际计算时数据来源都是从上方与左方,两种遍历顺序(横着遍历、竖着遍历)
都在计算前填充了上方与左方的数据因此遍历顺序可以交换
在这里插入图片描述

滚动数组思路

使用压缩了的一维 dp 数组用于记录
相当于把原来的二维数组沿着物品方向压缩,只留下不同背包容量下能装物品的最大价值
循环更新这个数组,故称滚动数组
可以理解为 dp 计算的时候是将第一层数据拷贝覆盖到下一层计算

Dp 数组

Dp[j]
Dp 数组中表示不同容量 j 下能装的物品的最大价值

递推公式确定

dp[j] = std::max(dp[j], dp[j - value[i]] + value[i])
取不放物品 i 与能放下物品 i 时的最大价值 + 物品 i 价值作为递推公式
可以理解为:要么不要物品 i,要么把背包空一空让他能装得下物品 i,物品 i 放进去看那个价值最大

初始化 dp 数组

dp[0]=0 dp[j]=0
0 初始化值为 0,1 初始化值为 0,如果初始化值很大就会覆盖计算结果,因此保证非负数最小值 0

遍历顺序

先遍历物品,再倒叙遍历背包,正序遍历背包会重复装东西
因为一维dp的写法,背包容量一定是要倒序遍历,如果遍历背包容量放在上一层,那么每个dp[j]就只会放入一个物品,即:背包里只放入了一个物品。
for(int i = 0; i < m; ++i) for (j=n; j>=0;--j)
倒叙为了保证物品不会被覆盖,因为 dp 是从前一个数据中退出来的
初始化时数据是正确数据,如果正序遍历背包会导致 dp 读取到之前的数据产生“左脚踩右脚起飞”的 bug,因此倒叙遍历保证数据正确
二维不受影响是因为二维 dp 数组数据是来源上一层数据,而不是当前层数据
一维正序会导致当前层数据覆盖了上一层数据,因此要倒叙利用上一层数据

题目

46. 携带研究材料(第六期模拟笔试)
二维数组实现方法
具体五部分析在上面的动态规划思路部分里面
注意遍历时的起始点 i = 1与终止点设置

#include<iostream>
#include<vector>int main() {// 输入数据处理int m = 0, n = 0;std::cin >> m >> n;std::vector<int> Space(m, 0);std::vector<int> Value(m, 0);for (int i = 0; i < m; ++i) std::cin >> Space[i];for (int j = 0; j < m; ++j) std::cin >> Value[j];// DP准备 +1 是因为结果都是从上一次中推导的,如果不+1相当于丢掉了[j-1]这个情况因此要+1std::vector<std::vector<int>> dp(m, std::vector<int>(n+1, 0));// DP初始化 j直接从Space[0]之后赋值,之前默认赋值为0了for (int j = Space[0]; j <= n; ++j) dp[0][j] = Value[0];// 循环遍历 先遍历物品再遍历背包for (int i = 1; i < m; ++i) {for (int j = 1; j <= n; ++j) {// 装不下if (j < Space[i]) dp[i][j] = dp[i-1][j];// 递推公式 不带物品i到当前最大能得到多少价值,带物品i当前能得到多少价值 取最大else dp[i][j] = std::max(dp[i-1][j], dp[i-1][j-Space[i]] + Value[i]);}}std::cout << dp[m-1][n] << std::endl;return 0;
}

46. 携带研究材料(第六期模拟笔试)
滚动数组实现方法
具体分析思路参考滚动数组思路部分
注意遍历时的起始点与终止点设置

#include<iostream>
#include<vector>int main() {// 公式化数据处理int m, n;std::cin >> m >> n;std::vector<int> Space(m);std::vector<int> Value(m);for (int i = 0; i < m; ++i) std::cin >> Space[i];for (int i = 0; i < m; ++i) std::cin >> Value[i];// 初始化dp数组 非负最小值std::vector<int> dp(n+1, 0);// 遍历顺序 先遍历物品再遍历背包 如果先遍历背包再遍历物品结果就是只能放进去一个物品for (int i = 0; i < m; ++i) {// 从后往前遍历是因为当前数据的计算依赖于前一次计算的数据,如果正序遍历会覆盖之前的数据for (int j = n; j >= Space[i]; --j) {// 如果背包容量比当前物品还小就不用比了dp[j] = std::max(dp[j], dp[j- Space[i]] + Value[i]);}}std::cout << dp[n] << std::endl;return 0;
}

416. 分割等和子集 - 力扣(LeetCode)
0-1 背包应用题,很难看出来,但是一旦看出来就好理解了
可以吧给出的数组看作是价值与重量两个数组,只不过他们的值相等
于是问题被转化为背包容量为(数组和/2)如何装最大价值的数据?
1. Dp 数组表示当前容量 j 下能装的最大价值是多少
2. 递推公式采用 0-1 背包递推公式
3. 初始化采用 0-1 背包初始化
4. 遍历顺序倒序遍历,防止新数据覆盖旧数据

bool canPartition(vector<int>& nums) {// 求和计算背包容量int sum = 0;for (int i = 0; i < nums.size(); ++i) sum += nums[i];// 剪枝 若为奇数不可能拆分if (sum % 2 == 1) return false;int target = sum/2;// 定义背包数组 数组元素不超过100 大小不超过200 总和不超过20000背包容量为10001即可 背包元素表示当前物体背包总价值std::vector<int> dp(10001, 0);// 初始化已定义 数据遍历for (int i = 0; i < nums.size(); ++i) {// 倒叙遍历 最大位置启动 j太小了装不下就放弃for (int j = target; j >= nums[i]; --j) {dp[j] = std::max(dp[j], dp[j - nums[i]] + nums[i]);}}if (dp[target] == target) return true;return false;
}
http://www.dtcms.com/wzjs/824059.html

相关文章:

  • Wordpress网站仿站myeclipse做网站的步骤
  • 手机怎么自己建网站网站内如何做内部链接
  • 中山台州网站建设推广宜家家居官网网上商城app
  • 免费网站建设多少钱网站建设找d云世家
  • 网站建设代码合同心跳直播视频免费下载
  • 网络网站建设公司排名公司建站服务
  • 企业网站推广技巧和方法安全教育平台作业登录入口
  • 怎么查一个网站的外链聊城推广网站
  • 有一个域名做网站wordpress 中文文档下载
  • 网站的建设与管理游戏logo设计网站
  • 学生做的动漫网站西安网站开发工资
  • 网站域名费一年多少钱老年大学网站开发
  • 莘县网站制作免费商标设计软件
  • 毕节金海湖新区城乡建设局网站文章时间分类wordpress
  • 北京建站哪家好电商设计个人作品集制作
  • 网站开发什么语言安全当阳网站建设电话
  • 杭州专业网站制作设计如何维护自己公司网站
  • 济南网站建设方案咨询淮安软件园哪家做网站
  • 北京视频网站建设网站怎么做友链
  • 绵阳网站托管网站开发与网页后台开发
  • 建筑网站设计模版电话推销网站建设
  • 搭建网站 软件下载网络营销的经济gdp是什么
  • 网站建设销售前景一个简单的网站怎么做
  • 专业网站开发平台番禺网站建设找哪家
  • 已经有了域名和服务器怎么做网站网络文化经营许可证有效期
  • 网站广告图片在线制作活动营销的方式有哪些
  • 设计师自己做网站wordpress表单收集
  • 网站图片布局河北网站建设seo优化
  • 节能环保公司网站建设如何用frontpage2003做网站
  • 徐州最好网站建设微官网建设