题目描述:有一个背包,能盛放的物品总重量为S,设有N件物品,其重量分别为w1,w2,...,wn.希望从N件物品中选择若干件物品,所选物品的重量之和恰能放入该背包,即所选物品的重量之和等于S。
要求:用非递归的方法。
便于理解,先说说递归算法。
非常简单:
int process(int s,int n)

{
if(s==0)return 1;
if(s<0||(s>0&&n<1))return 0;
if(process(s-w[n],n-1))

{
cout<<w[n];
return 1;
}
return process(s,n-1);
}
方法1:模拟堆栈
也很简单,先定义一个struct Node

typedef struct
{
int s;
int n;
int job; //1表示要,2表示不要
}Node;
然后将递归的方法用数组模拟出来,其实就是用数组实现进栈出栈。
int Process(int s,int n)


{
STACK stack[100],x;
int top,k,rep;
x.s=s;
x.n=n;
x.job=0;
top=1;
stack[top]=x;
k=0;

while(k==0&&top>0)
{
x=stack[top];
rep=1;

while(!k&&rep)
{
if(x.s==0)k=1;
else if(x.s<0||x.n<=0)rep=0;

else
{
x.s=x.s-w[x.n--]; //选取这个物品
x.job=1;
stack[++top]=x; //进栈
}
}

if(!k)
{ //总重量超出,需要丢弃其中的某个物品
rep=1;

while(top>=1&&rep)
{
x=stack[top--];

if(x.job==1)
{
x.s+=w[x.n+1]; //丢弃物品
x.job=2;
stack[++top]=x; //出栈
rep=0;
}
}
}
}

if(k)
{

while(top>=1)
{
x=stack[top--];
if(x.job==1)cout<<w[x.n+1];
}
}
return k;
}

这个程序算法不复杂,但是由于平时这种方法用得少,尤其是stack[top--] stack[++top]这种形式的东东容易搞错,所以考试的时候我只写了算法描述。
方法二: 注意到题目并没有限制算法的时间空间,我们用最暴力来解决:穷举法
#include <iostream>
using namespace std;
void main()


{
int i,j;
int n,s;//n为物品件数,s为背包容量
cin>>n;
//n = 10;
int *w = new int[n+1];//存储物品大小
int *y = new int[n+1];//物品是否被选中
for(i=1;i<=n;i++)


{
cin>>w[i];//输入物品大小
y[i]=0;
}
cin>>s;
//s = 21;
int t=0;
int flag=0;
while(1)


{
for(i=1;i<=n;i++)//把物品选中的整个串当作一个二进数,进行范围的全搜索

{
if(y[i]==0)

{
y[i]=1;
//cout<<"step in y[i]=0";
break;
}
else

{
if (i==n)

{
flag = 1;
}
y[i]=0;
continue;
}
}
t = 0;
for(j=1;j<=n;j++)

{
t = t+w[j]*y[j];
}
if(t == s)//判断是否求得解,求到解就直接退出

{
for(i=1;i<=n;i++)

{
if(y[i]==1) cout<<w[i]<<" ";
}
break;
}
if(flag == 1) //无解处理

{
cout<<"no answer"<<endl;
break;
}
}
}