输入样例:
3 5
2
1 2
2 4
1
3 4
1
4 5
输出样例:
8
分组背包问题与多重背包问题的区别
多重背包是第i种物品选几个或者不选,分组背包是第i组物品选哪个或者不选。
思路
我们可以使用v[i][k],w[i][k]分别存储第i组第k个物品的体积和价值,那么从第i组物品中选第k个物品的状态转移方程为f[j]=max(f[j],f[j-v[i][k]]+w[i][k]),下面上代码:
1.二维
#include<iostream>
using namespace std;
int f[105][105],v[105][105],w[105][105],s[105];
int main()
{
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>s[i];
for(int j=1;j<=s[i];j++)
cin>>v[i][j]>>w[i][j];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
f[i][j]=f[i-1][j];
for(int k=1;k<=s[i];k++)
{
if(j>=v[i][k])
f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);
}
}
cout<<f[n][m];
}
2.一维
#include<iostream>
using namespace std;
int f[105],v[105][105],w[105][105],s[105];
int main()
{
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>s[i];
for(int j=1;j<=s[i];j++)
cin>>v[i][j]>>w[i][j];
}
for(int i=1;i<=n;i++)
for(int j=m;j>=1;j--)
{
for(int k=1;k<=s[i];k++)
{
if(j>=v[i][k])
f[j]=max(f[j],f[j-v[i][k]]+w[i][k]);
}
}
cout<<f[m];
}