计算机算法基础(第三版)(余祥宣、崔国华、等)华中科技大学出版社 中回溯法解决01背包问题:
算法思想:
基于贪心算法的回溯算法:
W、P数组是按照效益P/W拍好序的数组
#include <stdio.h> const int N=8;//物品个数 const int M=110; int W[N+1]={0,1,11,21,23,33,43,45,55};//重量数组,从1开始 int P[N+1]={0,11,21,31,33,43,53,55,65};//效益数组 //最终的重量和收益 int fw=0; int fp=-1; int X[N+1]={0};//记录最终物品的状态 //当前重量和收益 int cw=0; int cp=0; int Y[N+1]={0};//当前物品的状态 //限界函数 //p:当前效益,w:当前背包重,k:上次去掉的物品 //返回新收益 int bound(int p,int w,int k){ for(int i=k+1;i<=N;i++){ w+=W[i]; if(w<M)p+=P[i]; else return p+(1-(w-M)/W[i])*P[i]; } return p; } void bag0_1(){ int k=1; while(true){ while(k<=N && cw+W[k]<=M){ cw+=W[k]; cp+=P[k]; Y[k]=1; k++; } if(k>N){ fp=cp; fw=cw; k=N; for(int i=0;i<=N;i++)X[i]=Y[i]; } else Y[k]=0; while(bound(cp,cw,k)<=fp){ while(k!=0&&Y[k]!=1) k--; if(k==0)return; Y[k]=0; cw-=W[k]; cp-=P[k]; } k++; } } int bound2(int p,int w,int k,int &pp,int &ww,int &i){ pp=p; ww=w; for(i=k+1;i<=N;i++){ if(ww+W[i]<=M){ ww+=W[i]; pp+=P[i]; Y[i]=1; } else return pp+(M-ww)*P[i]/W[i]; } return pp; } void bag0_1_2(){ int k=0,pp,ww,j; while(true){ while(bound2(cp,cw,k,pp,ww,j)<=fp){ while(k!=0&&Y[k]!=1) k--; if(k==0)return; Y[k]=0; cw-=W[k]; cp-=P[k]; } cp=pp; cw=ww; k=j; if(k>N){ fp=cp; fw=cw; k=N; for(int i=0;i<=N;i++)X[i]=Y[i]; } else Y[k]=0; } } int main(){ bag0_1_2(); printf("收益%d\n",fp); printf("重量%d\n",fw); for(int i=1;i<=N;i++)printf("%d ",X[i]); return 0; }
原文:http://blog.csdn.net/starcuan/article/details/20410573