0-1背包问题:求:从1,2,3,。。。n中取若干个数,使和为m,输出所有序列的非递归算法,其中,m>n #include <iostream> using namespace std; const int M = 100; int num; int st[M];//保存合理解 int a[5]={1,3,5,4,2};//物件重量 int top; void find1(int s,int n) { if(s==0) { for(int i = 0;i<num;i++) printf("%d ",st[i]); printf("/n"); return; } if(n<0 ||s<0) return; st[num]=a[n]; num++; find1(s-a[n],n-1); num--; find1(s,n-1); } /* *通过栈模拟递归过程 * */ void find2(int s,int n) { while(n>=0)//因为每次循环后n都是退栈的值,所以n>=0表明栈一定非空,否则栈也空,循环结束 { while(n>=0)//选取a[n],一直选下去,直到遇到s<=0或者选完所有的元素,如果遇到了s==0,输出一个可行解,恢复s的值(s+=a[st[top-1]]),然后退栈(即不选择栈顶元素),从栈顶元素的下一个元素开始重新循环“一直选下去”这个过程。当遇到s<0时,恢复s的值(s+=a[st[top-1]]),然后从栈顶元素的下一个元素开始重复上述过程。如果n<0(此时s>0),但是栈非空(top>0),退栈,继续重复 { s=s-a[n]; st[top++]=n; if(s<=0) break; n--; } if(s<=0) { if(s==0) { for(int i = 0;i<top;i++) printf("%d ",a[st[i]]); printf("/n"); } s+=a[st[top-1]];//使的刚进栈元素出栈,取下一个元素(栈顶元素-1)重复…… n=st[top-1]-1; top--; if(n<0)//如果此时n<0但是top>0,继续退栈 { n = st[top-1]-1;//退栈元素 s+=a[st[top-1]]; top--; } } else//本次取值已经考虑了所有的a[n-1]~a[0],此时n<0,此时s依然>0,退栈 { s+=a[st[top-1]]; top--; s+=a[st[top-1]];//退栈元素 n=st[top-1]-1; top--; } } } int main() { find2(8,4); }