当前位置:网站首页>动态规划背包问题之完全背包详解
动态规划背包问题之完全背包详解
2022-07-23 12:30:00 【四舍五入两米高的小晨】
上一篇我们学习了什么是动态规划问题和什么是背包问题,并且分析了01背包,如果想看上一篇请转移至–>背包问题之01背包详解,今天我们来了解一下背包问题之完全背包问题.
文章目录
一、什么是完全背包问题?
有n种物品,每种物品的单件体积为v[i],价值为w[i]。现有一个容量为V的背包,问如何选取物品放入背包,使得背包内物品的总价值最大。其中每种物品都有无穷件。
完全背包和01背包的区别:
- 01背包在选择某一个物品时只有不选和选一次两种情况
- 完全背包在选择某一个物品时可以不选,也可以选一次,选两次。。。选择次数没有上限(只要背包能放下)
二、例题分析
1. 题目:

2. 分析:
2.1 第一步:确定状态变量(函数)
最大价值是物品数量i和背包容量j的函数。
设函数f[i][j]表示前i件物品放入容量为j的背包的最大价值。
最终的最大价值就是物品数量i从0增长到n,背包容量j从0增长到m时的f[n][m]值。
2.2 第二步:确定状态转移方程
状态变量:f[i][j]表示前i件物品放入容量为j的背包的最大价值
当前容量为j,我们要考虑第i件物品能否放入?是否放入?
- 如果当前背包容量j<v[i],不能放入,则f[i][j]=f[i-1][j]
- 如果当前背包容量j>=v[i],能放入但是要比较代价
2.1 如果第i件物品不放入背包,则f[i][j]=f[i-1][j]
2.2 如果第i件物品放入背包,则f[i][j]=f[i][j-v[i]]+w[i]
对于前i件物品,背包容量为j-v[i]时可能已经放入了第i件物品,容量为j时还可以再放入第i件物品,所以用f[i][j-v[i]]更新f[i][j]
状态转移方程:
可以画图表示为:
2.3 边界条件
对于01背包来说边界就是f[i][j]=0,即当i=0或者j=0时f[i][j]的值为0。
i=0时,表示背包没有放入一个物品,那么此时背包的最大价值无从谈起,所以为0;
j=0时,表示背包的容量为0,那么此时无法放入物品,所以最大价值也为0;
3. 过程表示
3.1 核心代码
for(int i=1;i<=n;i++){
//物品i
for(int j=0;j<=m;j++)
{
if(j<v[i])
f[i][j]=f[i-1][j];
else
f[i][j]=max(f[i-1][j],f[i][j-v[i]]+w[i]);
}
}
cout<<f[n][m]<<endl;
3.2 手动计算

3.3 代码验证

3.4 完整代码
#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=1;j<=m;j++)
{
if(j<v[i])
f[i][j]=f[i-1][j];
else
f[i][j]=max(f[i-1][j],f[i][j-v[i]]+w[i]);
}
cout<<f[n][m]<<endl;
return 0;
}
3.5 优化
将二维表示优化成一维,减少空间的使用,用一维数组f[j]只记录一行数据,让j值顺序循环,顺序更新f[j]
优化后的代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1010;
int n,m;
int v[N],w[N];
int f[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=1;j<=m;j++)
{
if(j<v[i])
f[j]=f[j];
else
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
cout<<f[m]<<endl;
return 0;
}
因为j是顺序循环,f[j-v[i]]会先于f[j]更新,也就是说,用新值f[j-v[i]]去更新f[j],相当于用第i行的f[j-v[i]]值更新f[j],所以正确。
边栏推荐
- Why is apple x charging slowly_ IPhone 12 supports 15W MagSafe wireless charging. What will happen to iPhone charging in the future_ Charger
- pytest接口自动化测试框架 | 如何获取帮助
- Several common SQL misuses in MySQL
- 软件详细设计模板
- pytest接口自动化测试框架 | 控制测试用例执行
- nport串口服务器原理,MOXA串口服务器NPORT-5130详细配置
- Practice code - day one
- 死锁、饥饿、死循环之间的区别
- VMWARE平台STS证书过期
- Flutter 组件的生命周期、State 管理及局部重绘 | 开发者说·DTalk
猜你喜欢

SharedPreferences data storage

First hello of SOC_ World experiment

lc marathon 7.23

Mysql—主从复制

W3C introduces decentralized identifier as web standard

Bean validation core components - 04

死锁的3种处理策略

Governance and network security of modern commercial codeless development platform

vulnstack红日-4

Oracle中实现删除指定查询条件的所有数据
随机推荐
Mysql客户端到服务端字符集的转换
The difference between deadlock, hunger and dead cycle
1060 Are They Equal
GO语言学习——复习包、接口、文件操作
[cloud native] continuous integration and deployment (Jenkins)
How beautiful can VIM be configured?
Another award | opensca was selected as the "top ten open source software products in the world" at the China Software Expo
Vulnstack red sun-4
Why does fatal always appear when using opengaussjdbc? (tag database keyword user)
Basic concept and deployment of kubernetes
AC自动机和Fail树
Cloud native (11) | kubernetes chapter kubernetes principle and installation
Bean validation specification ----03
Bean validation core components - 04
低佣金账户怎么开?安全吗?
牛客-TOP101-BM35
聊一聊JVM的内存布局
Three handling strategies of deadlock
Mysql—主从复制
SharedPreferences data storage