大家好,我是Peter,我又来啦🎈🎄✨
🎈🧨🎉《动态规划》专栏来啦,目前为止,此专栏已经有四篇文章啦🎁🎀🎄
1.DP概念与编程方法 DP概念和编程方法-CSDN博客
2.Peter算法小课堂—经典线性DP问题(上)Peter算法小课堂—经典线性DP问题(上)-CSDN博客
3.Peter算法小课堂—经典线性DP问题(下)Peter算法小课堂—经典线性DP问题(下)-CSDN博客
4.Peter算法小课堂—DP的应用 Peter算法小课堂—DP的应用-CSDN博客
01背包
题目:小偷来你家,他带的包只能装c斤的财务。你家有n种财务,分别重w1、w2......wn斤,价值分别为v1、v2......,请输出能拿走的最大总价值?
状态定义
f[i][j]:用前i个物品,每个物品只能选或不选,满足重量和小于等于j的所有选法中,价值最高的那个方案
答案:f[n][c]
状态转移方程
首先,我们分两种情况讨论:1.选i 2.不选i
1。 此时我们重量和会变小w[i],但是价值会增加v[i],f[i][j]=f[i-1][j-w[i]]+v[i]
2。 此时物品数减1,f[i][j]=f[i-1][j]
最后,再取最大值,得到状态转移方程:f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i])
代码
for(int i=1;i<=n;i++) cin>>w[i]>>v[i];
for(int i=1;i<=n;++i){
for(int j=1;j<=c;++j){
if(w[i]>j) f[i][j]=f[i-1][j];
else f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);
}
}
cout<<f[n][c]<<endl;
咱再来开个滚动哈,这题完美解决
for(int i=1;i<=n;i++) cin>>w[i]>>v[i];
for(int i=1;i<=n;++i){
for(int j=c;j>=1;--j){
f[j]=max(f[j],f[j-w[i]]+v[i]);
}
}
cout<<f[c]<<endl;
我们看到,这个for循环里的i出现了2次,因此我们可以把w[i]写成w、v[i]写成v,这题再次完美解决
#include <bits/stdc++.h>
using namespace std;
const int MAXC=2009;
int n,c,w,v,f[MAXC];
int main(){
cin>>c>>n;
for(int i=1;i<=n;i++){
cin>>w>>v;
for(int j=c;j>=w;j--)
f[j]=max(f[j],f[j-w]+v);
}
cout<<f[c]<<endl;
return 0;
}
完全背包
题目:小偷来你家,他带的包只能装c斤的财务。你家有n种财务,每种数量无限多,分别重w1、w2......wn斤,价值分别为v1、v2......,请输出能拿走的最大总价值?
状态定义
f[i][j]:前i种物品,每个物品可以选0、1、2......,满足重量和小于等于j的所有选法中,价值最高为多少?
答案:f[n][c]
代码
cin>>c>>n;
for(int i=1;i<=n;i++){
cin>>w>>v;
for(int j=w;j<=c;j++)
f[j]=max(f[j],f[j-w]+v);
}
cout<<f[c]<<endl;
具体原因自行思考
希望这些对大家有帮助,粉丝破20更哦💟