简化01背包问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_44116998/article/details/101632974

题目描述
一个简化的背包问题:一个背包能装总重量为 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; 
}

运行结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44116998/article/details/101632974