二维背包
有总体积为V,且最大只能放质量为
M
M
M的背包中,存在n个物品,体积为
v
i
v_i
vi ,价值为
w
i
w_i
wi,质量为
m
i
m_i
mi,求怎么放可以得到最大价值。
总体来说就是在01背包的基础上为物品新增了一个重量的属性,代码还是比较简单,可以在我们之前的01背包的代码基础上加一层循环就ok了。并且我们至少需要一个二维数组
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示在背包体积为i,质量为j的情况下的最大价值。状态转移方程为
d
p
[
i
]
[
j
]
=
m
a
x
(
d
p
[
i
]
[
j
]
,
d
p
[
i
−
v
[
i
]
]
[
j
−
m
[
i
]
]
+
w
[
i
]
)
dp[i][j]=max(dp[i][j],dp[i-v[i]][j-m[i]]+w[i])
dp[i][j]=max(dp[i][j],dp[i−v[i]][j−m[i]]+w[i])
int n=1010;
int dp[n][n];
int Two_dimension_pack(vector<int>& v,vector<int>& w,vector<int>& m,int V)
{
for(int i=0;i<v.size();i++)
{
for(int j=V;j>=v[i];j--)
{
for(int k=M;k>=m[i];m--)
{
if(j>=v[i]&&k>=m[i])
dp[j][k]=max(dp[j][k],dp[j-v[i]][k-m[i]]+w[i]);
}
}
}
return dp[V][M];
}
分组背包
有总体积为V的背包中,存在n组物品,每组物品最多只能选一个,体积为
v
i
,
j
v_{i,j}
vi,j ,价值为
w
i
,
j
w_{i,j}
wi,j,
i
i
i组编号,
j
j
j是物品在组内的编号,
s
s
s是组内数量。求怎么放可以得到最大价值。
在01背包代码的基础上再加一层循环,判断
d
p
[
j
]
=
m
a
x
(
d
p
[
j
]
,
d
p
[
j
−
v
[
0
]
]
+
w
[
0
]
,
d
p
[
j
−
v
[
1
]
]
+
w
[
1
]
.
.
.
)
dp[j]=max(dp[j],dp[j-v[0]]+w[0],dp[j-v[1]]+w[1]...)
dp[j]=max(dp[j],dp[j−v[0]]+w[0],dp[j−v[1]]+w[1]...)
多重背包可以视为分组背包的一个特殊的情况,其每组内元素相同,所以他可以进行二进制优化,单调队列优化,但分组背包只能老老实实的进行三层循环。
int n=1010;
int dp[n];
int Group_pack(vector<int>& v,vector<int>& w,int V)
{
for(int i=0;i<v.size();i++)
{
for(int j=V;j>=v[i];j--)
{
for(int k=0;k<s;k++)
{
if(j>=v[k])
dp[j]=max(dp[j],dp[j-v[k]]+w[k]);
}
}
}
return dp[V];
}