(金明的预算方案)依赖性的背包

例题的话,可以看一下洛谷1064 金明的预算方案

原题链接 https://www.luogu.org/problemnew/show/P1064

有依赖性的背包,顾名思义,及选中其中一个物品,另一个物品必须随之选择

题意:

有n个物品,预算为V元,w[i]为每个物品的价格,v[i]为每个物品的重要程度,c[i]为每个数的主件,

如果c[i]为0,则代表该物品为主件,否则为c[i]的附件,每个物品的价值为w[i]*v[i],求最大的价值。

 

这就是典型的依赖性背包,我们可以首先可以用01背包的思想预处理出4种情况

1.只选择主件

2.选择主件且选择附件1 

3.选择主件且选择附件2 

4选择主件且选择附件1和附件2

这就是一个01背包,题目中保证每个主件只有两个附件,所以讲处理过的放入vector中,

接下来就是分组背包,因为选择了其中一种情况是不可能在选择其他的情况的

这题就可以a掉了

注意!!!

1.在预处理时不要忘了把主件加进去。

2.预处理出来如果一种情况与另一种情况的价值一样,则价格小的一定是最优的,见代码注释

#include <cstdio>
#include <cstdlib>
#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=60;
struct node
{
    int w,v;
    node(int ww,int vv)
    {
        w=ww,v=vv;
    }
};
vector <node> g[N],g1[N];
int n,V,v[N],w[N],c[N],dp[200005];
int main()
{
    scanf("%d %d",&V,&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d %d %d",&w[i],&v[i],&c[i]);
        v[i]=v[i]*w[i];
        if(c[i])
            g[c[i]].push_back(node(w[i],v[i]));
    }
    for(int i=1;i<=n;i++)
    {
        if(!g[i].empty())
        {
            memset(dp,0,sizeof(dp));
            for(int k=0;k<g[i].size();k++)
            {
                for(int j=V-w[i];j>=g[i][k].w;j--)
                {
                    dp[j]=max(dp[j],dp[j-g[i][k].w]+g[i][k].v);//01背包
                }
            }
            for(int j=1;j<=V-w[i];j++)
            {
                if(dp[j] && dp[j-1]!=dp[j])//此处为注意的第二点
                    g1[i].push_back(node(w[i]+j,dp[j]+v[i]));
            }
            g1[i].push_back(node(w[i],v[i])); //此处为注意的第一点
        }
        else if(!c[i])
        {
            g1[i].push_back(node(w[i],v[i]));//此处也为注意的第一点
        }
    }
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++)//分组背包
    {
        for(int j=V;j>=0;j--)
        {
            for(int k=0;k<g1[i].size();k++)
            {
                if(j>=g1[i][k].w)
                    dp[j]=max(dp[j],dp[j-g1[i][k].w]+g1[i][k].v);
            }
        }
    }
    printf("%d\n",dp[V]);
    return 0;
}

我居然写了两个小时,还是我太蒻了

 

posted @ 2018-10-11 17:31  没有名字的大佬  阅读(389)  评论(0编辑  收藏  举报