图片参考《算法图解》
假如你是一个小偷,你有一个4磅的背包,你可以偷下面物品,如何保证你能获得最大价值?
使用动态规划,动态规划是首先解决子问题然后再逐步解决大问题,对于背包问题,先解决小背包的问题,然后再解决原来的问题。
每一个动态规划的问题都是从网格开始的,背包问题的网格如下面:
首先是一件物品一件物品去放置,我们从吉他这一行开始。第一个单元格的质量为1磅,所以吉他的质量为1磅,可以放入,价值为1500元。
我们继续来看其他的格子,可以发现第2个格子也是完全足够的,第3个,第4个同理,因为是第一行只能放吉他,所以都是1500。
继续来看音响行,现在可以偷的东西有吉他(1磅),有音响(4磅)。
看到音响行第一个格子,我们可以看出音响太重放不下去。所以当前最大值也就是之前一行的最大值,依然是1500
所以类似往下面看,只有到了重量为4磅的格子的时候才放的下音响,而且价值比放吉他大,价格更新为3000
同理我们看到最后的笔记本电脑这一行。
#include <iostream>
using namespace std;
//定义物品数量
#define LENGTH 3
//定义背包容量
#define CAPACITY 4
void dynamic_pg(int weight[],int value[] ,int knapsack[][CAPACITY+1]){
for(int i = 1 ; i < LENGTH+1 ; i ++){ //循环物品数量,从第一种物品开始
for (int j = 1; j< CAPACITY+1 ; j ++){//循环背包容量,从背包容量为1开始
if (j < weight[i])
knapsack[i][j] = knapsack[i-1][j];//如果当前物品容量大于当前背包容量,就继续使用原来的物品
else{
knapsack[i][j] = max(knapsack[i-1][j],//上一个单元格的value
knapsack[i-1][j-weight[i]] + value[i]);//j-weight[i]:背包容量减去当前物品剩余的重量。value[i]当前物品的重量
//knapsack[i-1][j-weight[i]] 所以得到的就是背包剩余容量能放的最大价值,这里就体现出就是首先解决子问题,然后再解决大问题
}
cout << knapsack[i][j] <<' ';
}
cout << endl;
}
}
int main (){
int weight[LENGTH+1] = {0,1,4,3};//需要从数组下标为1开始赋值
int value[LENGTH+1] = {0,1500,3000,2000};
int knapsack[CAPACITY+1][CAPACITY+1] = {0};
dynamic_pg(weight,value,knapsack);
return 0;
}