问题描述:
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背包问题,就是求幂集问题。