0%

使用回溯法解决0/1背包问题

0/1背包问题一般是指指定容量的空间中,选择放入何种物品,使得其总价值最大。
常见的0/1背包求解方法有动态规划法,贪心算法和回溯法等等,今天分享的代码是使用回溯的方式求解0/1背包的问题。
本题同样来自算法课程的实验。

Test Case 测试用例

10
5
2 6
2 3
6 5
5 4
4 6

Except Result 预期结果

最大价值为 15
装入选择为 {1,1,0,0,1}

Code 实现代码 (C++)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include<iostream>
#include<cstring>
#define MAXN 1000

using namespace std;

int bag_size;
int item_count;
int item_weight[MAXN];
int item_price[MAXN];
int item_visited[MAXN];
int max_select[MAXN];
int max_price = 0;
int current_size = 0;
int current_price = 0;

void solve(){
for( int index = 0 ; index < item_count ; index ++){
if( !item_visited[index] && current_size + item_weight[index] <= bag_size ){
item_visited[index] = 1;
current_size += item_weight[index];
current_price += item_price[index];
if(current_price>max_price){
max_price = current_price;
for(int i = 0 ; i < item_count;i++){
max_select[i] = item_visited[i];
}
}
solve();
current_price -= item_price[index];
current_size -= item_weight[index];
item_visited[index] = 0;
}
}
}

int main(){
memset(item_weight,0,sizeof(item_weight));
memset(item_visited,0,sizeof(item_visited));
memset(item_visited,0,sizeof(item_price));
memset(item_visited,0,sizeof(max_select));
cout<<"背包最大重量: ";
cin>>bag_size;
cout<<"总计物品数量: ";
cin>>item_count;
cout<<"依次输入物品重量和价值,每组一行"<<endl;
for(int i = 0 ; i < item_count && i < MAXN; i ++ ){
cin>>item_weight[i];
cin>>item_price[i];
}
solve();
cout<<"最大价值为:"<<max_price<<endl;
cout<<"装入方法为 :{";
for( int i=0;i<item_count;i++){
if(i<item_count-1){
cout<<max_select[i]<<",";
}else{
cout<<max_select[i]<<"}"<<endl;
}
}
return 0;
}