P1064 金明的预算方案(有依赖的01背包)

传送门

题解:

这个题每一个物品最多只有两个附件,那么我们在对主件进行背包的时候,决策就不再是两个了,而是五个。

01背包的决策是:

1.不选,然后去考虑下一个

2.选,背包容量减掉那个重量,总值加上那个价值。

这个题的决策是五个,分别是:

1.不选,然后去考虑下一个

2.选且只选这个主件

3.选这个主件,并且选附件1

4.选这个主件,并且选附件2

5.选这个主件,并且选附件1和附件2.

所以附上代码:


#include<iostream>
#include<cstdio>

using namespace std;

const int maxn=32005;

int n,m;
int v,p,q;
int main_item_w[maxn];
int main_item_c[maxn];
int annex_item_w[maxn][3];
int annex_item_c[maxn][3];
int dp[maxn];

int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        cin>>v>>p>>q;
        if(!q){
            main_item_w[i]=v;
            main_item_c[i]=v*p;
        }else{
            annex_item_w[q][0]++;
            annex_item_w[q][annex_item_w[q][0]]=v;
            annex_item_c[q][annex_item_w[q][0]]=v*p;
        }
    }
    for(int i=1;i<=m;i++){
        for(int j=n;main_item_w[i]!=0&&j>=main_item_w[i];j--){
            dp[j]=max(dp[j],dp[j-main_item_w[i]]+main_item_c[i]);
            if(j>=main_item_w[i]+annex_item_w[i][1]){
                dp[j]=max(dp[j],dp[j-main_item_w[i]-annex_item_w[i][1]]+main_item_c[i]+annex_item_c[i][1]);
            }
            if(j>=main_item_w[i]+annex_item_w[i][2]){
                dp[j]=max(dp[j],dp[j-main_item_w[i]-annex_item_w[i][2]]+main_item_c[i]+annex_item_c[i][2]);
            }
            if(j>=main_item_w[i]+annex_item_w[i][1]+annex_item_w[i][2]){
                dp[j]=max(dp[j],dp[j-main_item_w[i]-annex_item_w[i][1]-annex_item_w[i][2]]+main_item_c[i]+annex_item_c[i][1]+annex_item_c[i][2]);
            }
        }
    }
    printf("%d\n",dp[n]);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值