题目描述:
现有一个能装下20kg的背包,和 [ 重量 , 价值 ]的珠宝分别为[2,3] [3,4] [4,5] [5,8] [7,10]的珠宝各一件,分别设为1-5号珠宝。
如何获得最大价值?
解题:
重量 | 价值 | |
1 | 2 | 3 |
2 | 3 | 4 |
3 | 4 | 5 |
4 | 5 | 8 |
5 | 9 | 10 |
设B(k,w)为,w为剩余的背包容量,k为前k个商品。
则B(k,w)的含义为,当背包容量为w时,偷前4个商品能获得的最大容量。
那么可以分为以下三种情况:
- 第k件珠宝已经装不下,那么B(k,w) = B(k-1,w)
- 第k件珠宝装得下,并偷走,那么B(k,w) = B(k-1,w-w_k) + v_k
- 第k件珠宝装得下,但是不偷,那么B(k,w) = B(k-1,w) (就是和第一种情况是一样的)
整个过程大概是就是如下图所示(懒的画那么多)
那么整个问题就可以对两种情况分别递归,最后比较两个递归得到的值
代码:
#include<iostream>
#include<algorithm>
using namespace std;
class Knapsack{
private:
int vs[6] = {0,3,4,5,8,10}; //价值
int ws[6] = {0,2,3,4,5,9}; //重量
public:
void Solution(int n){
int res = ks(5,n); //递归
cout<<res<<endl;
}
int ks(int k,int w){
int res = 0;
if( k==0 || w==0 )
return 0;
else if(ws[k]>w)
res = ks(k-1,w); //重量不够
else{ //重量够
int temp1 = ks(k-1,w-ws[k])+vs[k]; //偷
int temp2 = ks(k-1,w); //不偷
res = max(temp1,temp2);
}
return res;
}
};
int main(){
Knapsack test;
test.Solution(20);
return 0;
}