Peter算法小课堂—DP背包问题

大家好,我是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]

状态转移方程

Peter算法小课堂—DP背包问题_第1张图片

首先,我们分两种情况讨论: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<

咱再来开个滚动哈,这题完美解决

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<

我们看到,这个for循环里的i出现了2次,因此我们可以把w[i]写成w、v[i]写成v,这题再次完美解决

#include 
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<

 完全背包

题目:小偷来你家,他带的包只能装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<

具体原因自行思考

希望这些对大家有帮助,粉丝破20更哦

你可能感兴趣的:(动态规划,算法)