01背包的回溯法求解

笔记

回溯算法的基本结构是:
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;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值