P1064 金明的预算方案

对于各位dalao来说,这一定是一道水题吧。。。。。。

题意:m个物品,其中有主件附件,

   附件从属于某一主件,一个主件最多两个附件

   选附件必须选主件。。。。。(。。。)

考虑01背包

对于附件,有几种可能

无附件:主件自己是一个

有附件:有一个:主件自己和附件1

              有两个:主件自己和附件2

                            主件和两个附件

注意:不能重复选取,所以我们循环每个主件

          对所有 情况取max,遇到附件就跳过

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define love_nmr 0
#define olinr return 
int n;
int m;
int f[35050];
struct node
{
    int ji;
    int id[3];
    int val;
    int cost;
    int belong;
}s[36500];
int tot;
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    int x,y,z;
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y>>z;
        s[i].cost=x;
        s[i].val=y*x;
        if(z)
        {
            s[z].id[++s[z].ji]=i;
            s[i].belong=z;
        }
    }
    tot=m;
    for(int i=1;i<=m;i++)
        for(int j=n;j>=s[i].cost;j--)
        {
            if(s[i].belong) break;
            f[j]=max(f[j],f[j-s[i].cost]+s[i].val);
            if(s[i].ji)
            {
                if(j>=s[s[i].id[1]].cost+s[i].cost)
                    f[j]=max(f[j],f[j-s[s[i].id[1]].cost-s[i].cost]+s[s[i].id[1]].val+s[i].val);
                if(s[i].ji==2)
                {
                    if(j>=s[s[i].id[2]].cost+s[i].cost)
                        f[j]=max(f[j],f[j-s[s[i].id[2]].cost-s[i].cost]+s[s[i].id[2]].val+s[i].val);
                    if(j>=s[s[i].id[2]].cost+s[i].cost+s[s[i].id[1]].cost)
                        f[j]=max(f[j],f[j-s[s[i].id[2]].cost-s[i].cost-s[s[i].id[1]].cost]+s[s[i].id[2]].val+s[i].val+s[s[i].id[1]].val);
                }
            }
        }
    cout<<f[n];
    return 0;
}
原文地址:https://www.cnblogs.com/olinr/p/9458437.html