HDU 3449 有依赖的01背包

给出n个盒子,和总钱数w

对于n个盒子,首先买盒子需要花费m,然后可以买盒子中的物品,每个物品分别有其花费a[i].w和价值a[i].v

典型的有依赖的01背包


mark存储前i-1个盒子的dp值

然后对于当前盒子,先不考虑其盒子的花费进行01背包

然后对于mark数组的得到的每个新值mark[i},去更新dp[i+a[i].m];


#include "stdio.h"
#include "string.h"

struct node
{
    int n,m;
    int w[11],v[11];
} a[51];

int dp[100010],mark[100010];

int Max(int a,int b)
{
    if (a<b) return b;
    else return a;
}
int main()
{
    int n,w,i,j,k,ans;
    while (scanf("%d%d",&n,&w)!=EOF)
    {
        for (i=1; i<=n; i++)
        {
            scanf("%d%d",&a[i].m,&a[i].n);
            for (j=1; j<=a[i].n; j++)
                scanf("%d%d",&a[i].w[j],&a[i].v[j]);
        }

        memset(dp,0,sizeof(dp));

        for (i=1; i<=n; i++)
        {
            for (k=0; k<=w; k++)
                mark[k]=dp[k];
            for (j=1; j<=a[i].n; j++)
                for (k=w; k>=a[i].w[j]; k--)
                {
                    if (mark[k-a[i].w[j]] + a[i].v[j] >mark[k])
                        mark[k]=mark[k-a[i].w[j]]+a[i].v[j];
                }
            for (k=0; k+a[i].m<=w; k++)
                dp[k+a[i].m]=Max(dp[k+a[i].m],mark[k]);
        }
        ans=0;
        for (i=0; i<=w; i++)
            ans=Max(ans,dp[i]);
        printf("%d\n",ans);


    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值