版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
题目描述
一个简化的背包问题:一个背包能装总重量为 T,现有 n 个物件,其重量分别为(W1、W2、…、Wn)。问能否从这 n 个物件中挑选若干个物件放入背包中,使其总重量正好为 T ?若有解则给出全部解,否则输出无解。
思路解答
采用DFS的深度遍历的算法实现,在调用函数中设置一个for循环,定义每次第一个拿入背包的物品,在被调函数中,设置一个visited[ n ]数组,记录是否被访问,并且被拿入背包解赋值为一,否则默认为初始化时的零。在被调函数中每次查找下一个物品时,即调用自身函数后,将此时被调用的物品,比如物品i,就将visited [ i ] = 0,为//消除该值访问,进行下一个访问。
代码实现:
#include<iostream>
using namespace std;
#define Maxsize 100
int weight[Maxsize];
int T,n;
int count = 0;//计算可行解数量
int DFS(int order,int visited[],int sum)
{
int i,j = 0;
visited[order] = 1;//是否被访问
sum += weight[order];
if(sum == T)//恰好符合,返回1
return 1;
for( i = 0;i <= n -1;i++)
{
if(visited[i] == 1)//全部遍历完之后,没有执行上一句的return 1时,即表示误解
j++;
}
if(j == n)//本次递归无解
return 0;
for(i = order + 1;i <= n - 1;i++)//查找后面的元素
{
if(visited[i] == 0)//没有被访问时
{
if( DFS(i,visited,sum) == 1)//有解
{
for( int j = 0;j <= n - 1;j++)//输出该组解
{
if(visited[j] != 0)
cout<<weight[j]<<" ";
}
count++;//累计解的个数
cout<<endl;
}
visited[ i ] = 0;//消除该值访问,进行下一个访问
}
}
}
int main()
{
int i;
cout<<"请输入背包可装的总重量与可使用的物品数量(用空格分开):"<<endl;
cin>>T>>n;
cout<<"请输入每个物品的重量:"<<endl;
for( i = 0;i <= n - 1;i++)//重量输入
cin>>weight[i];
cout<<endl;
cout<<"该问题解的情况为:"<<endl;
for( i = 0;i <= n - 1;i++)
{
int visited[Maxsize] = {0};
int sum = 0;
DFS(i,visited,sum);//每次选取的开头所装物品序号,依次后推
}
if(count == 0)
cout<<"该问题无解"<<endl;
else
cout<<"该问题总的解的个数为"<<count<<endl;
return 0;
}
运行结果