一、问题分析
本题是一个典型的 0-1 背包问题。给定 n 件物品,每件物品只有 1 件,具有体积 v[i] 和价值 c[i]。背包的固定容量为 10,要求在不超过背包容量的前提下,选择若干物品使得总价值最大
约束条件:0 <= n <= 100,体积和价值均为整数。题目明确要求使用二维数组实现动态规划
二、算法思路
采用动态规划(Dynamic Programming)求解
状态定义
定义二维数组 dp[i][j],其中:
i 表示考虑前 i 件物品(从第 1 件到第 i 件);
j 表示当前背包的容量(取值范围为 0 到 10);
dp[i][j] 的值表示在前 i 件物品中选择,且背包容量为 j 时,能够获得的最大总价值
状态转移方程
对于第 i 件物品(体积 v[i],价值 c[i]),存在两种决策:
不选第 i 件物品:此时最大价值等于前 i-1 件物品在容量 j 下的最优解,即 dp[i-1][j]
选第 i 件物品:前提是当前容量 j 必须大于等于物品体积 v[i]。选取后,需要从容量 j - v[i] 的状态转移过来,并加上该物品的价值,即 dp[i-1][j - v[i]] + c[i]
初始化
dp[0][j] = 0(0 <= j <= 10):表示没有物品可选时,任何容量下的最大价值均为 0
dp[i][0] = 0(1 <= i <= n):表示容量为 0 时,无法放入任何物品,最大价值为 0
由于 C++ 全局数组默认初始化为 0,因此无需显式初始化
遍历顺序
外层循环遍历物品编号 i,从 1 到 n;
内层循环遍历容量 j,从 0 到 10(顺序遍历即可,因为二维数组中的 dp[i] 只依赖 dp[i-1] 行的数据,不会产生覆盖问题)
最终答案
输出 dp[n][10],即考虑全部 n 件物品、背包容量为 10 时的最大价值
三、代码实现
四、总结
这道题其实就是一个 “选还是不选” 的决策问题
我们可以这样想:
行表示“已经看了前几件商品”
列表示“背包还剩多大容量”
格子里填的是“当前情况下能拿到的最大价值”
每加入一件新商品时,我们只需要比较两种情况:
不拿:价值和之前一样
拿(前提是装得下):腾出空间,加上这件商品的价值
两者取更优的那个
最后得到的数字,就是答案
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这个我真的做了很久,点赞+关注,求求了