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

/**简单背包问题问题定义:有一个背包重量是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,没有访问过为0int 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++){//如果没有被访问过,并且加上重量之和小于Sif(!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 < 1knap(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;}

摘抄美文4、承诺是一件美好的事情,但美好的东西往往不会变为现实。

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

相关文章:

你感兴趣的文章:

标签云: