回溯——“子集之和”问题

来源:互联网 发布:新网域名管理 编辑:程序博客网 时间:2024/06/07 07:23

0-1背包问题这种问题属于子集之和问题:有n个正整数wi和一个正整数W,要求从这n个正整数中找出之和为W的子集。

我们先将所有wi按照非递减的顺序排列,然后建立状态空间树,有n+1级,每一级表示是否含有排序后的wi元素,从起点开始,左子树表示含有该元素,右子树表示不含有该元素。依此类推,还可以对状态空间树进行修剪,当前总量+剩余总量<W时,该结点是无希望的;当当前总量>W时,该节点也是无希望的;

int sumOfSubjects(index i,int wight,int total)//i;从w[i]开始判断;wight:要求总量;total: 剩余总量 {if(promise(i))//该节点是有希望的 if(weight==W)cout<<include[1...i];//输出包含情况 else{include[i+1]=1;//包含 w[i+1]sumOfSubjects(i+1,wight+w[i+1],total-w[i+1]);include[i+1]=0;//不包含 w[i+1]sumOfSubjects(i+1,wight,total-w[i+1]);}}bool promise(index i){return (wight+total>=W)&&(wight==W||weight+w[i+1]<=w);}
顶级调用为
sumOfSubjects(0,0,total)
算法中不需要判断i=n为终止条件,因为当i=n是total=0;意味着上一级中wight+total>=W,则这一级中wight+total>=W恒成立,若相等则符合条件,输出;若大于则wight>W不符合后面的条件,跳出;



原创粉丝点击