回溯法求解,每次每个物品都有放与不放两种情况,每次放时要判断是否能放。
#include<iostream>
using namespace std;//回溯函数定义,rw 剩余容量,i第i个物品,v体积数组,number到第i个物品处有几种装法,n物品总数
int backtrack(int rw, int i, int *v, int number, int n);
//回溯法背包问题
//背包容量w
//n个零食,每个零食体积为v[i]
//输入:
//n w
//v[0]...v[n-1]
//输出
//最多几种装法,什么也不装也算一种
//例如,输入为
//3 10
//1 2 4
//输出为
//8
//
//例如,输入为
//3 10
//1 9 4
//输出为
//6
//
//例如,输入为
//3 10
//5 5 3
//输出为
//7
int main() {
int n;
cin >> n;
int w;
cin >> w;
int* v = new int[n];
for (int i = 0; i < n;i++) {
cin >> v[i];
}
//排序,从小到大
for (int i = 0; i < n;i++) {
for (int j = i; j < n; j++)
{
if (v[i] > v[j]) {
int tmp = v[i];
v[i] = v[j];
v[j] = tmp;
}
}
}
int result = 1;
result=backtrack(w,0,v,result,n);
cout << result;
system("pause");
return 0;
}
//rw 剩余容量,i第i个物品,v体积数组,number到第i个物品处有几种装法,n物品总数
int backtrack(int rw,int i,int *v,int number,int n) {
int tmp1 = 0;//i装的方法数
int tmp2 = 0;//i不装的方法数
if (i == n) {
//装与不装都是一种方法
return 1;
}
number++;
if (rw >= v[i]) tmp1=backtrack(rw-v[i],i+1,v,number,n);
number--;
tmp2=backtrack(rw , i + 1, v, number, n);
return tmp1 + tmp2;//返回放与不放两种方法的总和
}