背包问题的递归和非递归算法

匿名 (未验证) 提交于 2019-12-03 00:34:01
/** 简单背包问题 问题定义: 有一个背包重量是S,有n件物品,重量分别是W0,W1...Wn-1 问能否从这n件物品中选择若干件放入背包中使其重量之和正好为S */ #include <iostream> #include <algorithm> #include <vector> #include <string> using namespace std; const int maxsize=100; int n,S;//n是有多少中物品,S是要凑足的重量 bool visit[maxsize];//标记是否被访问过,别访问过标记为1,没有访问过为0 int w[maxsize];//记录每一种物品的重量 int q[maxsize];//相当于一个栈,存储被访问过的物品的编号 int beibao() {     int top=-1,begin=0,sum=0;     int i;     while(top!=-2)     {         //从第一个物品开始循环         for(i=begin;i<n;i++)         {             //如果没有被访问过,并且加上重量之和小于S             if(!visit[i] && w[i]+sum<=S)             {                 sum+=w[i];//在sum上加上当前物品的重量                 q[++top]=i;//把物品的编号存入q[]中                 begin=0;//从头开始访问                 visit[i]=1;//该结点访问过标记                 if(sum==S) return top;//如果成功,返回top,top为数组元素的个数,有所有物品的编号                 break;             }         }         //如果检索到最后,也就是说栈顶前面的物品都不符合条件         //因此可能栈内的元素有问题,所以弹出栈顶元素,不把栈顶元素计算在内         if(i==n)         {             visit[q[top]]=0;//把栈顶元素定义成未访问             sum-=w[q[top]];//从和中减去站定物品编号的重量             begin=q[top]+1;//从栈顶元素的下一个物品开始检索             //cout<<"------"<<begin<<endl;             top--;//栈递减一个单位         }     } } //背包问题递归版本 /** 解释:其选择只有两种可能,选择一组物品中包含Wn-1 ,此时knap(s,n)的解就是knap(s - Wn-1,n-1)的解 如果选择的物品中不包括Wn-1,这样knap(s,n)的解就是knap(s,n-1)的解 knap(s,n) = true, 当 s=0时             false ,当s < 0 或者 s > 0 且 n < 1             knap(s - Wn-1,n-1) || knap(s,n-1) 当s>0且n>=1 */ bool knap(int s,int n) {     if(s == 0) return true;//递归出口 在s恰好为0时 递归结束     if(s < 0 || (s > 0&&n < 0)) return false;//或者s小于0 n 小于0时     if(knap(s - w[n - 1],n - 1))     {         cout<<w[n - 1];         return true;     }else return knap(s,n - 1); } int main() {     cin>>n>>S;     for(int i=0;i<n;i++)     {         cin>>w[i];         visit[i]=0;     }     int t=beibao();     knap(S,n);     if(t!=-1)     {         for(int i=0;i<=t;i++)             cout<<w[q[i]]<<" ";         cout<<endl;     }     else cout<<-1<<endl; }

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!