0-1背包DP自学笔记
1.0-1背包DP自学笔记
0-1背包
- 这种背包每个物品只有拿与不拿两种状态
转移方程推导:
设 DP 状态
考虑转移。假设当前已经处理好了前
由此可以得出状态转移方程:
这里如果直接采用二维数组对状态进行记录,会出现 MLE。可以考虑改用滚动数组的形式来优化。
由于对 f[i] 有影响的只有 f[i-1] ,可以去掉第一维,直接用 f[i] 来表示处理到当前物品时背包容量为 i 的最大价值,得出以下方程:
例题
有
思路
- 这道就是一个非常简单的背包模板,可以直接套用上文公式进行求解
AC代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=20000;
int n,W,w[maxn],v[maxn],f[maxn];
int main() {
cin>>n>>W;
for (int i = 1; i <= n; i++) cin>>w[i]>>v[i];
for(int i=1;i<=n;i++){
for(int j=W;j>=w[i];j--){
f[j]=max(f[j-w[i]]+v[i],f[j]);
}
}
cout<<f[W];
return 0;
}
注意!!!
初学很容易写出错误核心代码:
for(int i=1;i<=n;i++){
for(int j=0;j<= W-w[i];j++){
f[j+w[i]]=max(f[j]+v[i],f[j+w[i]]);
}
}
这段代码枚举顺序错了。
仔细观察代码可以发现:对于当前处理的物品
为了避免这种情况发生,我们可以改变枚举的顺序,从
因此实际核心代码为:
for(int i=1;i<=n;i++){
for(int j=W;j>=w[i];j--){
f[j]=max(f[j],f[j-w[i]]+v[i]);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人