蛮力法解决01背包问题,详细讲解,c语言,c++

问题描述:

   01背包问题就是给你一个容量有限的背包,再给你一些物品,每个物品都有自己的重量和价值,每个物品不能被分割开来,要你从这些物品中挑出合适物品装入背包,使得背包的价值最大,且不超重。

算法描述:

蛮力法解决01背包问题,所谓蛮力法就是求出所有的物品的组合,从所有组合种类中挑出重量不超标,价值最大的组合。这个货物组合就是最优解。

代码描述:

   求出所有货物组合就相当于求出幂集,关于求解1-n的幂集,不太了解的小伙伴们可以阅读

幂集问题详细解读

我们这里用到两个一维数组来存放物品的价值和重量,用二进制遍历来求幂集。筛选所有的物品组合情况,找出最优解。用到了vector容器来代表背包,存放当前最优解,关于vector容器的简单使用

  给出背包容量10,给出4个物品的重量为{7,4,3,5},价值为{42,40,12,25}

#include<stdio.h>
#include<iostream>
#include<math.h>
#include<vector>
using namespace std;

//给定4个物品的重量为{7,4,3,5},价值为{42,40,12,25},和一个容量为10的背包
//改用二进制求幂集的方法解01背包问题
void add(int b[], int n)//二进制进位
{
	for (int i = 0; i < n; i++)
	{
		if (b[i])
		{
			b[i] = 0;
		}
		else
		{
			b[i] = 1;
			break;//进一位后要退出!!!!!!!!!!!!
		}
	}
}
void pack01()
{
	int a[] = { 7,4,3,5,6 };  //数组a分别存放物品的重量
	int b[] = { 42,40,12,25,26 };  //数组b分别存放物品的价值
	int n = sizeof(a) / sizeof(a[0]);//物品的种数
	int c[10];//数组c存放二进制
	for (int i = 0; i < n; i++)//初始化二进制0
	{
		c[i] = 0;
	}
	int pw = (int)pow(2, n);//代表二进制的所有种类
	int endv = 0;//代表最终价值
	vector<int>backpack;//定义一个容器代表背包存放当前最优货物组合
	for (int i = 0; i < pw; i++)//遍历二进制,每一种货物组合
	{
		int weight = 0;
		int value = 0;
		for (int j = 0; j < n; j++)//输出二进制
		{
			if (c[j])
			{
				weight = weight + a[j];
				value=value+b[j];
			}
			if (weight<=10 && value>endv)//这个货物组合没超重,且价值大于当前的最优组合
			{
				backpack.clear();//存放之前清空背包
				endv = value;
				for (int m = 0; m < n; m++)//把这个货物组合放入背包
				{
					if (c[m])
					{
						backpack.push_back(m + 1);
					}
				}

			}
		}
		add(c, n);//二进制进位,求下一个货物组合
	}
	cout <<"最终价值"<< endv<<endl;
	for (auto it = backpack.begin(); it != backpack.end(); it++)//输出最终背包里货物的信息
		{
			cout <<"存放了"<< * it << "号货物 " << endl;
		}
}
int main()
{
	pack01();
	return 0;
}

上述代码用二进制进位遍历求幂集,在求幂集文章中另一种方法求幂集也可以来解决01背包问题。

简单说 蛮力法01背包问题,就是求幂集问题

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值