92 背包问题
Posted tang-tangt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了92 背包问题相关的知识,希望对你有一定的参考价值。
原题网址:https://www.lintcode.com/problem/backpack/description
描述
在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i]
你不可以将物品进行切割。
样例
如果有4个物品[2, 3, 5, 7]
如果背包的大小为11,可以选择[2, 3, 5]装入背包,最多可以装满10的空间。
如果背包的大小为12,可以选择[2, 3, 7]装入背包,最多可以装满12的空间。
函数需要返回最多能装满的空间大小。
挑战
O(n x m) time and O(m) memory.
O(n x m) memory is also acceptable if you do not know how to optimize memory.
思路:
背包问题是动态规划的一种题型,它的特点如下:
1. 用值作为dp维度
2. dp过程就是填写矩阵
3. 可以用滚动数组进行优化 转自此文
dp【i】【j】表示前 i 个物品放到容量为 j 的背包里能够占用的最大体积。
状态转移方程为:dp【i】【j】= max(dp【i-1】【j】,dp【i-1】【j-A【i】】+A【i】)。
每个物品只有两种状态,放或者不放。对于容量为 j 的背包,放入第 i-1 件物品后占用的最大体积为dp【i-1】【j】,现在考虑第 i 件物品。
不放,dp【i】【j】=dp【i-1】【j】;
放,需要从 j 中腾出A【i】的空间,再看剩余的空间放前 i-1 件物品最大能占多少空间,即dp【i】【j】=A【i】+ dp【i-1】【j-A【i】】。(注意前提是 j >= A【i】)
最后的dp【i】【j】就是上述两种情况的较大值。
AC代码:
class Solution {
public:
/**
* @param m: An integer m denotes the size of a backpack
* @param A: Given n items with size A[i]
* @return: The maximum size
*/
int backPack(int m, vector<int> &A) {
// write your code here
if (A.empty())
{
return 0;
}
int size=A.size();
vector<vector<int>> dp(size,vector<int>(m+1,0));
//初始化第一行,即只有第一个物品时,若背包容量大于等于A[0],放物品能占用的最大空间为A[0];
for (int j=0;j<=m;j++)
{
if (j>=A[0])
{
dp[0][j]=A[0];
}
}
//计算dp其他元素;
for (int i=1;i<size;i++)
{
for (int j=0;j<=m;j++)
{
if (j>=A[i])//能放A[i],计算此时的最大体积,注意是大于等于;
{
dp[i][j]=dp[i-1][j-A[i]]+A[i];
}
dp[i][j]=max(dp[i-1][j],dp[i][j]);
}
}
return dp[size-1][m];
}
};
PS:状态转移方程简而言之就是,背包容量为 j 时,能放得下 i 就腾出A【i】的空间,再看剩余的空间放前 i-1 件物品最大能占多少空间,二者之和与不放 i 能占用的最大体积比,哪个大就取哪个;放不下就直接看0~i-1能占用 j 的最大容量是多少;
参考:
LintCode背包问题总结 总结了一系列背包问题,可以好好参考。
以上是关于92 背包问题的主要内容,如果未能解决你的问题,请参考以下文章