题目;依赖背包。。
购物,买相应物品时,必须先买其对应的箱子。。以及n个盒子的价钱和,该盒子中所可以装的物品的价格和价值。
求最大价值!!
一般的:
dp[i][j]=dp[i][j-cost[i]]+value[i];
但需要考虑盒子的价值。故
dp[i][j]=max(dp[i-1][j],max(dp[i-1][j-k]+pack[i][k]));
其中dp[i][j]表示使用前i个盒子,花费j所得到的最大价值;考虑第i个盒子到底选不选以及选的话,该多花多少钱,很明显时间复杂度高,故优化;
仔细分析会发现dp[i-1][j-k]+pack[i][k]是在考虑第i个盒子的情况下的最大价值;
将盒子的价值当做0,在金钱j下,首先将盒子的价钱考虑进去,那么剩下的只是挑选盒子中的物品,即01背包;
令f(i,j)为前i个盒子且第i个一定考虑在内的情况下的最大价值,所以初始化为f(i,j)=max(f[i][j-box[i]]+0)(PS:初始化后,盒子的影响就没有了);之后01就可以了!
#include"stdio.h"
#include"string.h"
#define max(x,y) x>y?x:y;
int dp1[100001];
int dp2[100001];
int main()
{
int n,w,i,j,k;
int cost[55][11],value[55][11];
int num[55],box[55];
while(scanf("%d%d",&n,&w)!=-1)
{
for(i=1;i<=n;i++)
{
scanf("%d",&box[i]);
scanf("%d",&num[i]);
for(j=1;j<=num[i];j++)
scanf("%d%d",&cost[i][j],&value[i][j]);
}
memset(dp1,0,sizeof(dp1));
for(i=1;i<=n;i++)
{
for(j=w;j>=box[i];j--)
dp2[j]=dp1[j-box[i]];//初始化,消除盒子的影响!!
for(j=1;j<=num[i];j++)
{
for(k=w;k>=cost[i][j]+box[i];k--)
dp2[k]=max(dp2[k],dp2[k-cost[i][j]]+value[i][j]);
}
for(j=w;j>=box[i];j--)
dp1[j]=max(dp1[j],dp2[j]);//更新dp1
}
printf("%d\n",dp1[w]);
}
return 0;
}