题目大意:
FJ要去购物,他要用一些盒子去装要买的材料,每个盒子都有自己可以装的材料类型,价格pi元,可放物品有mi种,物品价格和价值分别为cj和vj,现在他有W元,要使得购买的材料价值最大。
解决方案:
这题可以用有依赖的背包问题去解决。对于每一个盒子,判断在购买了这个盒子情况下,相同的金钱获得的最大价值;再计算在相同的金钱下,是买了当前盒子及物品赚还是不买赚。用f[i]来表示用了i元的情况下获得的最大价值。用ary[i]来表示前面的物品购买以及当前盒子的物品购买后(未购买盒子)用了i的最大价值。转移方程是ary[i]=max(ary[i],ary[i-当前物品价格]+当前物品价值),f[i]=max(f[i],ary[i-盒子价格]);时间复杂度是O(n*m*w)。
代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int max(int a,int b)
{
if (a>b) return a; else return b;
}
int main()
{
int n,w;
int f[120000],ary[120000];
while (scanf("%d%d",&n,&w)!=EOF)
{
memset(f,0,sizeof(f));
for (int i=1;i<=n;i++)
{
int pri,m;
for (int j=0;j<=w;j++) ary[j]=f[j];
scanf("%d%d",&pri,&m);
for (int j=1;j<=m;j++)
{
int c,v;
scanf("%d%d",&c,&v);
for (int k=w;k>=c;k--)
ary[k]=max(ary[k],ary[k-c]+v);
}
for (int k=w;k>=pri;k--)
f[k]=max(f[k],ary[k-pri]);
}
int max1=0;
for (int i=0;i<=w;i++)
max1=max(max1,f[i]);
printf("%d\n",max1);
}
return 0;
}