dp01背包

文章转载自
读这篇文章之前,建议先读一下链接博主的文章,我刚开始看没有太理解,后来发现博主写的不错,然后又写了一些当时不太懂得地方。所有引用都是博主所写

  1. 第一个解释:

这是题的几个重要信息

Vi表示第 i 个物品的价值,Wi表示第 i 个物品的体积,定义V(i,j):当前背包容量 j,前 i 个物品最佳组合对应的价值,

也是引用的博主的

这个表格其实代表的是代码中的dp[i][j],**当前背包容量 j,**当时怎么也理解不了这个地方,
我以为这个包一开始就假设它的体积就是8,在前i个物品中组合,组合出最优解后包的体积还剩j,
所以说dp[4][8]=10,我就不大理解了,认为应该是 dp[4][0]=10,就是一共四种物品,从其中选了几种后组成最优解,当前包的体积还有0,后来再一想,dp是子问题求解,
想起老师画的图

在这里插入图片描述
所以先是想包有1这么大,他的最优解是几,然后再想包有2那么大,他的最优解是甚么,一直求到包的体积是8

#include<iostream>
using namespace std;
#include <algorithm>
 
int w[5] = { 0 , 2 , 3 , 4 , 5 }; //商品的体积2、3、4、5
int v[5] = { 0 , 3 , 4 , 5 , 6 }; //商品的价值3、4、5、6
int bagV = 8;         //背包大小
int dp[5][9] = { { 0 } };         //动态规划表
int item[5];         //最优解情况
 
void findMax() { //动态规划
 for (int i = 1; i <= 4; i++) {//四个物品 
 for (int j = 1; j <= bagV; j++) {//例如当i是1时,,表示只有编号为1的物品,
                                 //当体积是j时的最优解 
 if (j < w[i])
 dp[i][j] = dp[i - 1][j];
 else
 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
 }
 }
}
 
void findWhat(int i, int j) { //最优解情况i是物品总的种类,j是包的体积 
 if (i >= 0) {
 if (dp[i][j] == dp[i - 1][j]) {//如果编号为i的没有放进去,就item[i]=0; 
 item[i] = 0;
 findWhat(i - 1, j);
 }
 else if (j - w[i] >= 0 && dp[i][j] == dp[i - 1][j - w[i]] + v[i]) {
 item[i] = 1;//说明他在 最优解中 
 findWhat(i - 1, j - w[i]);
 }
 }
}
 
void print() {
 for (int i = 0; i < 5; i++) { //动态规划表输出
 for (int j = 0; j < 9; j++) {
 cout << dp[i][j] << ' ';
 }
 cout << endl;
 }
 cout << endl;
 
 for (int i = 0; i < 5; i++) //最优解输出
 cout << item[i] << ' ';
 cout << endl;
}
 
int main()
{
 findMax();
 findWhat(4, 8);
 print();//动态规划表输出
 
 return 0;
}//
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值