分组背包问题
- 分组背包问题相当于在背包问题的逻辑之上,将物品分成不同的组,每一组当中各个物品有拥有不同的权重与体积,对于每一组只能选出一个物品放到背包里面
- 在分组背包问题当中,存储物品的权重与体积的时候必须用二维数组,表示是哪一组的且在该组当中的第几个物品的体积或权重,并且创建一个数组s,用来表示每一组当中物品的个数。
int v[N][N];
int w[N][N];
int s[N];
- 在分组背包问题当中的状态表示的集合f(i,j ),表示在只选前 i 组的情况之下,并且物品总体积小于等于j,在该状态之下的所有选法当中权重和的最大值
- 然后再进行状态计算的时候,可以得出一个状态转移方程如下,划分集合的依据就在于:对于第i组到底选择他这个组当中的第几个物品,也可以不选
for (int i=1;i<=n;i++)
{
for (int j=0;j<=m;j++)
{
for (int k=0;k<=s[i];k++)
{
if (j-v[i][k]>=0)
{
f[i][j]=MAX(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);
}
}
}
}
printf("%d\n",f[n][m]);
分组背包问题
来源:AcWing
luck
#include <stdio.h>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define N 110
int n,m;
int v[N][N];
int w[N][N];
int s[N];
int f[N][N];
int main()
{
scanf("%d %d",&n,&m);
for (int i=1;i<=n;i++)
{
scanf("%d",&s[i]);
for (int j=1;j<=s[i];j++)
{
scanf("%d %d",&v[i][j],&w[i][j]);
}
}
for (int i=1;i<=n;i++)
{
for (int j=0;j<=m;j++)
{
for (int k=0;k<=s[i];k++)
{
if (j-v[i][k]>=0)
{
f[i][j]=MAX(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);
}
}
}
}
printf("%d\n",f[n][m]);
return 0;
}