对于每个物品,我们都有选或者不选两种选择,因此我们可以用dfs来寻找出将所有物品考虑完后能获得的最大价值
上代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int *wi, *vi;//分别表示重量和价值
int n, m;
int dfs(int x, int Spv)//x代表当前访问到了第几个,Spv表示背包剩余容量
{
if(x > n) return 0;//此时所有的物品都已经考虑完了,因此返回0
else{
if(Spv < wi[x]){//如果当前重量大于剩余容量,就返回
return dfs(x + 1, Spv);
}
else if(Spv >= wi[x]){//如果当前重量小于等于剩余容量,就返回选或者不选的最大价值
return max(dfs(x + 1, Spv - wi[x]) + vi[x], dfs(x + 1, Spv));
}
}
}
int main(void)
{
cin >> n >> m;
wi = new int[n + 10];
vi = new int[n + 10];
for(int i = 1; i <= n; i++){
cin >> wi[i] >> vi[i];
}
cout << dfs(1, m) << endl;
return 0;
}
但是dfs过于暴力,只能通过部分案例
我们可以对dfs进行记忆化搜索优化
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 5050;
int mem[N][N] = {0};//记忆数组
int *wi, *vi;//分别表示重量和价值
int n, m;
int dfs(int x, int Spv)//x代表当前访问到了第几个,Spv表示背包剩余容量
{
if(mem[x][Spv]) return mem[x][Spv];//如果当前记忆数组已经存储,就返回当前值
int sum = 0;
if(x > n) return 0;//此时所有的物品都已经考虑完了,因此返回0
else{
if(Spv < wi[x]){//如果当前重量大于剩余容量,sum就直接等于不选的价值
sum = dfs(x + 1, Spv);
}
else if(Spv >= wi[x]){//如果当前重量小于等于剩余容量,sum就等于选或者不选的最大价值
sum = max(dfs(x + 1, Spv - wi[x]) + vi[x], dfs(x + 1, Spv));
}
}
mem[x][Spv] = sum;
return sum;
}
int main(void)
{
cin >> n >> m;
wi = new int[n + 10];
vi = new int[n + 10];
for(int i = 1; i <= n; i++){
cin >> wi[i] >> vi[i];
}
cout << dfs(1, m) << endl;
return 0;
}
通过优化可以通过所有案例