背包问题(动态规划)
假设有一个背包负重最多可达8公斤,求出使背包所装的物品价值之和最高的组合。假设所装物品为水果,水果信息如下,分别是水果的编号、名称、重量、价格:
背包问题是一个最优化的问题,计算机的最优化问题都可以用动态规划,从空集合开始,每增加一个元素就先求出该阶段的最优解,知道所所有的元素加入集合
什么是动态规划呢?就是将问题分解为许多复杂度更小的子问题,而复杂度大的问题又可以利用子问题来简化复杂度,进而起到了将复杂度降小的目的。
此问题:value[]数组存储上一个状态的最优解下的最大价值,item[]数组存储最后一个放入背包的水果(方便最后求最优解的水果组成)
核心思路:需要求出1~8公斤每种容量的最优解,本质上动态规划还是穷举,只不过穷举的有技巧,这是计算机不同于人的地方。此问题又叫0-1背包,因为对于每一种水果,只有两种状态,放进背包和不放进背包
#include <iostream>
#include <string.h>
#include <stdio.h>
#define limit 8 //背包最大负重量
#define N 5 // 水果种数
#define Min 1 // 最轻的水果
using namespace std;
typedef struct node
{
char name[20];
int weight;
int price;
}Fruit;
int main()
{
int value[limit+1]={0};//初始状态为0,不放水果
int item[limit+1]={0};
int newvalue,p,coun=0;
Fruit a[] = {
{"梨子",4,4500},
{"苹果",5,5700},
{"橘子",2,2250},
{"草莓",1,1100},
{"甜瓜",6,6700},
};
for(int i=0; i<N; i++) //依次放入水果
{
for(int s=a[i].weight; s <= limit; s++) //s代表背包最大负重
{
p = s-a[i].weight;//背包的最大负重-放入的水果的重量
newvalue = value[p]+a[i].price;//若放入此水果,背包的价值
if(newvalue > value[s]) //若将次水果放入背包后价值增加
{
value[s] = newvalue;
item[s] = i;//将此水果的编号放入item[]数组
}
}
}
for(int i=limit; i>=Min; i = i-a[item[i]].weight)
{
cout<<a[item[i]].name<<endl;
coun += a[item[i]].price;
}
cout<<coun;
return 0;
}