书包问题

来源:互联网 发布:冰封王座不能连入网络 编辑:程序博客网 时间:2024/04/28 00:00
#include <iostream>using namespace std;// abstract data type for stack template <class T> // 栈的元素类型为 Tclass Stack { public:             // 栈的运算集void clear();   // 变为空栈   bool push(const T item); // item入栈,成功则返回真,否则返回假 bool pop(T* item);// 返回栈顶内容并弹出,成功返回真,否则返回假, bool getTop(T* item);  // 返回栈顶内容但不弹出成功返回真,否则返回假,   bool isEmpty();    // 若栈已空返回真   bool isFull();        // 若栈已满返回真};//  array-based stack: definition and implementation for some methodstemplate <class T> class arrStack: public Stack<T> {      private:                     // 栈的顺序存储intmSize;// 栈中最多可存放的元素个数T *st;  // 存放栈元素的数组public:           inttop;// 栈顶位置,应小于mSize public:  // 栈的运算的顺序实现arrStack(int size)  { // 创建一个顺序栈的实例mSize = size;top = -1;st = new T[mSize];}~arrStack() {// 析构函数delete [] st;}void clear() {// 清空栈内容top = -1;    }bool push(const T item) {    // 入栈操作的顺序实现if (top == mSize-1) {  // 栈已满 cout << "栈满溢出" << endl;return false;}else {// 新元素入栈并修改栈顶指针st[++top] = item;return true;}}bool pop(T* item) {                           // 出栈的顺序实现if (top == -1) {                       // 栈为空cout << "栈为空,不能出栈操作"<< endl; return false;}else {*item = st[top--];         // 返回栈顶元素并修改栈顶指针return true;}}bool getTop(T* item) {     // 返回栈顶内容,但不弹出if (top == -1) {         // 栈空cout << " 栈为空,不能出栈操作"<< endl; return false;}else { *item = st[top];return true;}    }    bool isEmpty() {          return (top == -1);    }    bool isFull() {          return (top == mSize-1);    }};bool knap(int s, int n);bool nonRecKnap(int s, int n);bool nonRecKnapOpt(int s, int n);enum rdType {a, b, c}; class knapNode {      friend  bool nonRecKnap(int s, int n);      friend  bool nonRecKnapOpt(int s, int n);       int s, n;        // 背包的承重量和物品的数目       rdTyperd;   // 返回地址       boolk;      // 结果单元}; // 引入两个与栈中结点类型相同的变量tmp和x作为进出栈的缓冲:class knapNode tmp, x;// 定义一个栈变量://Stack<knapNode> st(20); int w[5] = {2,4,4,5,7};int main() {    int s;        cin >> s;         cout << "recursion" << endl;     if (knap(s, 5))          cout << "Have solution" << endl;    else  cout << "No solution" << endl;                  cout << "non recursion" << endl;      if (nonRecKnap(s, 5))          cout << "Have solution" << endl;    else  cout << "No solution" << endl;       cout << "non recursion optimization" << endl;         if (nonRecKnapOpt(s, 5))          cout << "Have solution" << endl;    else  cout << "No solution" << endl;cin >> s;        return 0;} //递归版的背包问题 bool knap(int s, int n) {if (s == 0)  return true;if ((s < 0)||(s>0 && n <1))return false; if (knap(s-w[n-1], n-1)) {cout << w[n-1];return true;} else knap(s, n-1); }// 非递归的机械版 bool nonRecKnap(int s, int n) {     arrStack<knapNode> st(20);  tmp.s = s,  tmp.n = n,  tmp.rd = a; // 非递归调用入口st.push(tmp);  label0: // 递归调用入口st.pop(&tmp); if (tmp.s == 0 ) { tmp.k = true;// 修改栈顶的结果单元kst.push(tmp);            goto label3;}        if ((tmp.s < 0) || (tmp.s > 0 && tmp.n < 1)) {tmp.k = false;// 修改栈顶的结果单元kst.push(tmp);            goto label3;}st.push(tmp);        x.s = tmp.s-w[tmp.n-1]; // 按照规则1进行压栈处理x.n = tmp.n -1;x.rd = b;st.push(x);goto label0;label1: // 规则1对应的返回处理st.pop(&x);// 查看栈顶,根据其内容分情况处理        if (tmp.k == true) {// 若某层的结果单元为truex.k = true;// 把true结果上传给调用方st.push(x);cout << w[x.n-1]<<endl;// 并输出对应的物品goto label3;}st.push(x);// 若某层的结果单元为false        tmp.s = x.s;// 当前物品的选择不合适,回溯,调用规则2tmp.n = x.n - 1;// 按照规则2进行压栈处理tmp.rd = c;st.push(tmp);goto label0;   label2: // 规则2对应的返回处理st.pop(&x);x.k = tmp.k;// 结果单元k的内容上传给调用方st.push(x);     label3:// 递归出口处理st.pop(&tmp);switch (tmp.rd) {case a:  return tmp.k; // 算法结束并返回结果case b:goto label1;// 转向规则1的返回处理处 case c:goto label2;// 转向规则2的返回处理处}} // 非递归的优化版 bool nonRecKnapOpt(int s, int n) {int t, n0 = n;    bool k = false;    arrStack<knapNode> st(20);      tmp.s = s, tmp.rd = a; st.push(tmp);while (!st.isEmpty()) {t = st.top;st.getTop(&tmp);while ((tmp.s >= 0) && (tmp.s <= 0 || n0 > t)){  //处理栈顶元素,以判断是否满足递归出口条件              if (tmp.s == 0 ) { k = true;break;  } else {// 尚未递达归出口前,按规则1进行压栈操作x.s = tmp.s - w[n0 - 1 - t];x.rd = b;st.push(x);  }  t = st.top;  st.getTop(&tmp);}while (!st.isEmpty()) {// 返回处理              st.pop(&tmp);              t = st.top;              if (tmp.rd == 0) // 算法结束                 return k;               if (tmp.rd == 1) // 从规则1返回         if (k == true) // 结果为真则打印对应的物品                       cout << w[n0 - 1 - t]<<endl;                 else {// 否则回溯,采用规则2进栈                      st.getTop(&x);                      tmp.s = x.s;                      tmp.rd = c;                      st.push(tmp);                      break;}}}} 

原创粉丝点击