笔记
回溯算法的基本结构是:
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
对应结构的回溯函数如下:
// An highlighted block
void backtrack(int n,int wLimit,int *w,int*v,int l){
//回溯法尝试
if(l>n){
//l代表遍历树的层次,到了叶节点后遍历结束;
if(NowV>MaxV)
MaxV = NowV;
}
else{
//非叶节点
for(int i=0;i<=1;i++){
//两种操作
if(i==0) backtrack(n,wLimit,w,v,l+1);//下一层
else{
if(NowW+w[l]<=wLimit){
NowW+=w[l];
NowV+=v[l];
backtrack(n,wLimit,w,v,l+1);
NowW-=w[l];
NowV-=v[l];
}
}
}
}
}
完整代码如下:
#include<stdio.h>
int MaxV=0;
int NowW=0;
int NowV=0;
void backtrack(int n,int wLimit,int *w,int*v,int l){
//回溯法尝试
if(l>n){
//l代表遍历树的层次,到了叶节点后遍历结束;
if(NowV>MaxV)
MaxV = NowV;
}
else{
//非叶节点
for(int i=0;i<=1;i++){
//两种操作
if(i==0) backtrack(n,wLimit,w,v,l+1);//下一层
else{
if(NowW+w[l]<=wLimit){
NowW+=w[l];
NowV+=v[l];
backtrack(n,wLimit,w,v,l+1);
NowW-=w[l];
NowV-=v[l];
}
}
}
}
}
int main(){
//int weight[51]={0,6,4,10,11,1,9,9,3,8,8,12,13,0,13,6,11,11,9,8,9,2,5,12,9,0,11,13,9,2,11,5,2,7,5,11,13,11,1,5,7,4,7,0,2,9,4,3,4,2,12};//50件商品的重量
//int value[51]={0,11,39,9,58,12,23,34,32,45,18,36,51,11,9,37,7,13,2,2,0,4,42,57,10,47,2,31,3,31,45,23,21,22,55,3,22,19,38,6,54,11,10,6,18,51,32,31,43,42,27};//50件商品的价值
//int weight[21]={0,6,4,10,11,1,9,9,3,8,8,12,13,1,13,6,11,11,9,8,9};//20件商品的重量
//int value[21]={0,11,39,9,58,12,23,34,32,45,18,36,51,11,9,37,7,13,2,2,0};//20件商品的价值
int weight[11]={0,6,4,10,11,1,9,9,3,8,8};//10件商品的重量
int value[11]={0,11,39,9,58,12,23,34,32,45,18};//10件商品的价值
//int weight[11]={0,6,4,10,11,8};//5件商品的重量
//int value[11]={0,11,39,9,58,18};//5件商品的价值
int number=10;
int weightLimit=20;
//结果
int MaxValue=0;
backtrack(number,weightLimit,weight,value,1);
printf("回溯求解值:MaxValue==%d\n",MaxV);
return 0;
}