如果你对动态规划方法求解0-1背包问题的思路不清晰,直接阅读代码并不是一个好的建议。
推荐一个B站up主的视频讲解:
0/1背包问题-动态规划
练习地址(B站视频配套的网址)
#include<iostream>
using namespace std;
const int bagVolume = 6;//背包体积
const int itemNumber = 4;//准备放入的物品数量
const int rows = itemNumber + 1;//table表格的行:0,1,2,3,4 共5个数
const int cols = bagVolume + 1;//table表格的列:0,1,2,3,4,5,6 共7个数
void knapsack(int table[][cols], int weight[], int value[])
{
int wt, vl;//wt是weight,vl是value
for (int i = 1; i < rows; i++)
{
wt = weight[i-1];
vl = value[i-1];
for (int j = 1; j < cols; j++)
{
/*
if (wt > j)//如果weight大于当前的背包容量j,
{
table[i][j] = table[i-1][j];//那么此物品放不进背包
}
else//如果weight小于当前的背包容量j,
{ //那么,就判断(table[i-1][j-wt] + vl) 是不是大于 table[i-1][j]。如果大于,那么就table[i][j]=(table[i-1][j-wt] + vl);反之...
table[i][j] = (table[i-1][j-wt] + vl) > table[i-1][j] ? (table[i-1][j-wt] + vl) : table[i-1][j];
}
*/
//简化写法
table[i][j] = wt > j ? table[i-1][j] : ((table[i-1][j-wt] + vl) > table[i-1][j] ? (table[i-1][j-wt] + vl) : table[i-1][j]);
}
}
cout<<"动态规划表:"<<endl;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
string str = table[i][j] >= 10 ? " " : " ";//如果是一位数就返回5个空格字符串,是两位数就返回4个空格字符串。
cout<<table[i][j]<<str;
}
cout<<endl;
}
cout<<"放入背包的物品有:"<<endl;
//打印放入背包的物品编号
int j = bagVolume, sum_value=0;
for (int i = itemNumber; i > 0; i--)
{
if (table[i][j] != table[i-1][j])
{
cout<<"【物品"<<i<<"】"<<endl;
sum_value += value[i-1];
j = j - weight[i-1];
}
}
cout<<"背包中物品最大价值总和为:"<<sum_value<<endl;
}
int main()
{
int table[rows][cols] = {0};
int weight[itemNumber] = {2,2,4,2};
int value[itemNumber] = {8,5,10,3};
knapsack(table, weight, value);
return 0;
}