用最小的空间装最大价值的物品是经典的背包问题,而0-1背包是背包问题中最简单的情况,常见的做法有动态规划和回溯法等。
本文用更为容易理解的回溯法来解决该问题。
我们把每个输入的物品都看做一个节点,用标记数组来标记是否使用该物品,于是物品节点之间能够生成一颗二叉树,二叉树节点的左子(1)表示装该物品,右子(0)表示不装该物品。
于是我们可以从二叉树的根节点用深度优先搜索的方法来遍历直到叶子节点,我们对每条路径可以得到一个有效序列来标记是否在背包中装这n个物品(假设n=8,则例如:01100010)可以给出装下3个物品的背包情况。
当然,每次确定装或不装某物品时,我们都要计算当前背包总重,在DFS的同时,如果发现当前背包装的总物品重量过大,则可以直接剪枝,从而大幅度提高程序效率。
注意:通常不只有一种情况可以产生最大价值。
程序如下:
#include<iostream>
using namespace std;
int weight[1001],value[1001];//重量和价值
int use[1001];//标记n个物品是否使用
int c; //背包容量
int max_value=0;//最大价值
int b_count; //记录最大价值的数量
void find_max_value(int n,int max){
int w=0;
for(int i=0;i<n;i++) w+=weight[i]*use[i]; //算总重
if(w>c) return; //如果超重,回溯
else if(n==max){
int v=0;
for(int i=0;i