回溯法 01背包
代码:
#include <iostream>
using namespace std;
const int M = 100; //设物品最多100个
int n, MaxWight, SumValue;
int wight[M], value[M], ans[M], a[M];
void backtrack(int t, int Swight, int Svalue)
{
// cout << t << " " << Swight << " " << Svalue << endl; 调试的时候可以输出数据做参考
if (t >= n)
{
if (SumValue < Svalue)
{
SumValue = Svalue;
for (int i = 0; i < n; i++)
ans[i] = a[i];
}
}
else
{
for (int i = 0; i <= 1; i++)
{
a[t] = i;
Swight = Swight + i * wight[t];
Svalue = Svalue + i * value[t];
if (Swight <= MaxWight)
{
backtrack(t + 1, Swight, Svalue);
}
else //实际重量大于最大重量时,从背包把物品拿出。
{
Swight = Swight - i * wight[t];
Svalue = Svalue - i * value[t];
}
}
}
}
int main()
{
cin >> n >> MaxWight;
for (int i = 0; i < n; i++)
cin >> value[i];
for (int i = 0; i < n; i++)
cin >> wight[i];
backtrack(0, 0, 0);
for (int i = 0; i < n; i++)
cout << ans[i];
cout << endl
<< SumValue << endl;
return 0;
}
n 代表的是物品个数
MaxWight 背包能装的最大体积
SumValue 物品的最大价值
ans 数组,最终选择方式
a 数组,临时选择方式
思路:物品只有两种选择,放或者不放,构造二叉树,n 个物品就是 n 层树,然后进行最优值更新。
样例:

图1
背包构造出的二叉树如图1,顺序三从右边到左边,也就是先不放物品,然后再慢慢放进去。
输入:
3 30
45 25 25
16 15 15
输出:
0 1 1 :放进后面 2 件物品。 50 : 最大价值
附回溯法搜索子集树模板:
void backtrack(int k)
{
if(到达边界) 更新或者输出结果
else
{
对于每一种可能进行操作(for循环 i)
{
if(限定条件合法)
backtrack(k+i);
}
}
}

浙公网安备 33010602011771号