hdu 3449(依赖背包)

本文介绍了一种特殊的分组背包问题解决方法,其中购买每组内的物品必须先购买该组的盒子。通过将盒子视为单独物品,并使用动态规划来跟踪最大价值,确保正确处理物品与盒子之间的依赖关系。

题意:每一组物品都有一个盒子,要买该组的物品必须先要买盒子,问能够获得的价值最大是多少。


解题思路:这题有点像分组背包,但是每一组里面要买物品必须要先买盒子。其实我的想法还是和分组背包的思路一样,只是把盒子看成一个单独的物品,dp[i][j]表示前i组物品,容量为j时的最大价值。为了防止盒子没有买就买了这一组的物品,我们最开始的dp[i][j]赋值为-1,在该组里做一次01背包,同样,还是需要做一次分类,该组里面的物品是第一个放入的还是之前已放入过其他物品。但如果认为这样就完成任务了,那么就game over了,如果该组没有一个放入背包,那么dp[i]的所有值都会为-1,连之前的状态都会丢失,所以还要把之前的值复制过来。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int n,m,box[55],cost[55][11],value[55][11];
int dp[55][100005],num[55];

int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(dp,-1,sizeof(dp));
		memset(dp[0],0,sizeof(dp[0]));
		for(int i = 1; i <= n; i++)
		{
			scanf("%d",&box[i]);
			scanf("%d",&num[i]);
			for(int j = 1; j <= num[i]; j++)
				scanf("%d%d",&cost[i][j],&value[i][j]);
		}
		int ans = 0;
		for(int i = 1; i <= n; i++)
		{
			for(int j = 1; j <= num[i]; j++)
				for(int v = m; v >= cost[i][j]; v--)
				{
					if(dp[i][v-cost[i][j]] != -1)	//之前就放过物品了,直接01背包
						dp[i][v] = max(dp[i][v],dp[i][v-cost[i][j]]+value[i][j]);
					if(v >= box[i] + cost[i][j])	//该组里面第一个放入背包的物品
					{
						if(dp[i-1][v-box[i]-cost[i][j]] != -1)
							dp[i][v] = max(dp[i][v],dp[i-1][v-box[i]-cost[i][j]]+value[i][j]);
					}
				}
			for(int v = 0; v <= m; v++)
				dp[i][v] = max(dp[i][v],dp[i-1][v]);
		}
		printf("%d\n",dp[n][m]);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值