问题:小偷偷4个背包,容量为8,背包如下
![](https://i-blog.csdnimg.cn/blog_migrate/201c887bc0b2d6cd2b4d2415af668e80.png)
问题类型:(Dynamic Programming,DP),即决策规划,用在多种决策可能情况下求最大值的类型题。如背包问题。
思想及方法:找到每个阶段的所得值与上个阶段的关系,分多种情况讨论(如采取或不采取该阶段,两种可能的分布都列出来),从最后的阶段倒着返回到最初,并且找到假如只有第一阶段的值。
对于该问题,f(k,w)表示取第k个包时,还有w的容量,从第四个取到第一个。取第k个包时,第一种情况,第k个包的空间比总容量大,只能取下一个包,即 = f (k-1,w);
第二种情况,第k个包的空间比总容量小,可以取或不取,那么就选取或不取这两种情况的最大值,
取的话,记得要减去容量,并把总价值加上该包的价值,不取则与第一种情况一样
即=max((f(k-1,w-wk)+vk)+ f(k-1,w) );
得到关系式:
![](https://i-blog.csdnimg.cn/blog_migrate/8bb5d95edb1386b2451d75e8ce27b4ad.png)
且当k=0时,f的值为0
代码解释:
一 以结构体方式存储背包数据
struct node{
int weight;
int value;
}a[100];
二 构造该阶段与上一决策之间的关系
及f(k,w)=
![](https://i-blog.csdnimg.cn/blog_migrate/8bb5d95edb1386b2451d75e8ce27b4ad.png)
int f(int k,int w){
if(k==0) return 0;//假如只有第一个阶段
if(a[k].weight>w){
return f(k-1,w);
}
if(a[k].weight<=w){
return max((f(k-1,w-a[k].weight)+a[k].value),f(k-1,w));
}
}
递归到第一个决策时,得出结果,所有代码如下
#include<bits/stdc++.h>
using namespace std;
struct node{
int weight;
int value;
}a[100];
int f(int k,int w){
if(k==0) return 0;
if(a[k].weight>w){
return f(k-1,w);
}
if(a[k].weight<=w){
return max((f(k-1,w-a[k].weight)+a[k].value),f(k-1,w));
}
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
cin>>a[i].weight>>a[i].value;
}
printf("%d",f(n,m));
return 0;
}