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;
}

猜你喜欢

转载自blog.csdn.net/zhouzi2018/article/details/82696681