【34. 完全背包】
思路
0 1 背包在进行状态计算时,集合的划分,是第i个选择1个还是0个进行划分
完全背包问题的状态表示与0 1背包一样,状态计算中的集合划分不一样(由于第i个物品有无限个,可以按照第i个物品选多少个进行划分,分成若干组,第一块代表第i个物品选择1个,第二块代表第i个物品选2个)
- k是枚举的第i个物品的个数,因为有容量限制,所以不可能无限大,不能超过背包容量
题目
代码
#include <iostream>
#include <algorithm>
using namespace std;const int N = 1010;
int n, m;
int v[N], w[N];
int f[N][N];int main()
{cin >> n >> m;for (int i = 1; i <= n; i ++) cin >> v[i] >> w[i];for (int i = 1; i <= n; i++){for (int j = 0; j <= m; j++){for (int k = 0; k * v[i] <= j; k ++){f[i][j] = max(f[i ][j], f[i - 1][j - k * v[i]] + k * w[i]);}}}cout << f[n][m];return 0;
}
优化为二维
我们列举一下更新次序的内部关系:
- 之前要枚举K个状态,现在只需要枚举俩个状态就可以
注意:
0 1 背包都是从i - 1层转移过来
完全背包是从第i层转移过来
f[i , j ] = max( f[i-1,j] , f[i-1,j-v]+w , f[i-1,j-2*v]+2*w , f[i-1,j-3*v]+3*w , .....)
f[i , j-v]= max( f[i-1,j-v] , f[i-1,j-2*v] + w , f[i-1,j-3*v]+2*w , .....)
由上两式,可得出如下递推关系: f[i][j]=max(f[i,j-v]+w , f[i-1][j])
有了上面的关系,那么其实k循环可以不要了,核心代码优化成这样
for(int i = 1 ; i <=n ;i++)
for(int j = 0 ; j <=m ;j++)
{f[i][j] = f[i-1][j];if(j-v[i]>=0)f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i]);
}
优化为一维
- 这个代码和01背包的非优化写法很像啊!!!我们对比一下,下面是01背包的核心代码
for(int i = 1 ; i <= n ; i++)
for(int j = 0 ; j <= m ; j ++)
{f[i][j] = f[i-1][j];if(j-v[i]>=0)f[i][j] = max(f[i][j],f[i-1][j-v[i]]+w[i]);
}
两个代码其实只有一句不同(注意下标)
f[i][j] = max(f[i][j],f[i-1][j-v[i]]+w[i])
;//01背包f[i][j] = max(f[i][j],f[i][j-v[i]]+w[i])
;//完全背包问题
因为和01背包代码很相像,我们很容易想到进一步优化。核心代码可以改成下面这样
for(int i = 1 ; i<=n ;i++)for(int j = v[i] ; j<=m ;j++)//注意了,这里的j是从小到大枚举,和01背包不一样{f[j] = max(f[j],f[j-v[i]]+w[i]);}
综上所述,完全背包的最终写法如下:
#include<iostream>
using namespace std;
const int N = 1010;
int f[N];
int v[N],w[N];
int main()
{int n,m;cin>>n>>m;for(int i = 1 ; i <= n ;i ++){cin>>v[i]>>w[i];}for(int i = 1 ; i<=n ;i++)for(int j = v[i] ; j<=m ;j++){f[j] = max(f[j],f[j-v[i]]+w[i]);}cout<<f[m]<<endl;
}
完全背包与多重背包
- 完全背包问题不可以用单调队列优化, 而多重背包问题可以用单调队列优化
- 在多重背包里面求的时候是求滑动窗口的内的最大值(
滑动窗口一般可以用单调队列优化
) - 完全背包是求从1开始的最大值,每次多一个数,求前面所有的最大值,这个可以用一个变量来存
- 在多重背包里面求的时候是求滑动窗口的内的最大值(
【34. 完全背包】相关推荐
- 算法第四版学习(chapter1.3)
前几天,回了老家,怠惰了几天,把云图看了,还看了一季的King of the hill ,简直爽爆,回来了,又要开始学习了,今天我们来学习几种极为常见的数据结构,分别是背包.队列还有栈. 1.3.1: ...
- 牛客挑战赛34 A 能天使的愿望 (dp 分组背包)
链接:https://ac.nowcoder.com/acm/contest/2271/A 来源:牛客网 题目描述 出题人寄给大家的一些闲话:参加了CSP-J/S 2019 的同学,考的都怎么样啊?不 ...
- 牛客挑战赛34 A.能天使的愿望(分组背包)
链接:https://ac.nowcoder.com/acm/contest/2271/A 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 65536K,其他语言1310 ...
- HDU-1203 I NEED A OFFER!-0、1背包及空间优化
I NEED A OFFER! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- POJ 3260 多重背包+完全背包
前几天刚回到家却发现家里没网线 && 路由器都被带走了,无奈之下只好铤而走险尝试蹭隔壁家的WiFi,不试不知道,一试吓一跳,用个手机软件简简单单就连上了,然后在浏览器输入192.168 ...
- 分组背包----HDU1712 ACboy needs your help
很简单的一道分组背包入门问题.不多解释了. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring&g ...
- hdu 3732(01背包转多重背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3732 思路:这么大的数据,用01背包肯定会TLE的,01背包转多重背包..最多也就11*11=121件 ...
- 洛谷 P1049 装箱问题(01背包)
一道水题,但看到好久没有发博客了,再一看是一道noip普及组t4,就做了. 题目链接 https://www.luogu.org/problemnew/show/P1049 解题思路 一道裸的01背包 ...
- HDu 3449 (有依赖的01背包) Consumer
题意: 有n件物品,对应有不同的价格和价值,这是典型的01背包.但现在有了一个限制,要买物品先买能装这件物品的特定的盒子,盒子的价值为0 代码理解得还不是太好,感觉这是一个"二重" ...
最新文章
- Facebook AI的多任务多模态的统一Transformer
- 怎么跑都不累?自然医学揭秘微生物组提升运动表现
- stream获取filter
- java环境变量一闪而过_Java环境变量配置和Tomcat启动时cmd界面一闪而过问题
- 高级语言中的关键字:const用法分析
- 个人简介页面如何设计?集设网优秀案例给你灵感
- [struts2学习笔记] 第五节 编写struts2的action代码
- 1.4.2.PHP5.6 狐教程-环境(Mac下 PHP开发环境 配置及安装 php5.6.x nginx mysql)
- python鼠标移动_python自动化之鼠标移动
- rom lg g2 f320d android 4.4.2,LG G2(F320K/S/L/D8001/D802)官方KDZ刷机教程
- 北大核心2020_“三个月不录用视为拒稿”,核心期刊投稿,编辑的这句话别有用意...
- C语言的结构化程序设计
- 《增长黑客》:针对产品增长---思维导图
- 帧率FPS,屏幕刷新频率赫兹Hz
- Hyperledger Fabric 链码生命周期
- Cannot run code from this file in conjunction with non encoded files
- 面试中常问的你在项目开发中遇到过哪些问题怎么回答?
- 权限系统(vue+elementui)设计
- upload 上传文件之前判断,先判断再弹出文档选择框
- 系统检测效果html,系统检测(MonitorTest)