P1064 金明的预算方案 简要解析

题目链接:P1064 金明的预算方案

简要分析:  

  •   将每个主件和附件进行组合,然后做分组背包
  •   坑点:
    1.  附件有可能比主件更早出现
    2.    编号实际是指行数,而非第几个组件

代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=10000;
int F[maxn*1000],v[100][5],c[1010][5];//c[]指代价,w[]指价值,T[]指第k组的件数
int T1[100][5],T2[100][5];
int N,V;
inline long long Read(void)
{
    int w=0,x=0;
    char ch=0;
    while(!isdigit(ch))w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
    return w?-x:x;
}
int main(void)
{
    V=Read(),N=Read();//输入
    for(int i=1; i<=N; ++i)    T1[i][0]=1;
    for(int i=1; i<=N; ++i)
    {
        int t1=Read(),t2=Read(),t3=Read();//t1为价格,t2为重要的,t3为组别
        if(t3==0)//主件
        {
            T1[i][1]=t1;
            T2[i][1]=t2*t1;
        }
        else
        {
            T1[t3][0]++;
            T1[t3][T1[t3][0]]=t1;
            T2[t3][T1[t3][0]]=t2*t1;
        }
    }
    for(int k=1; k<=N; ++k)
    {
        for(int i=1; i<=T1[k][0]; ++i)
        {
            if(i==1)
            {
                c[k][++c[k][0]]=T1[k][i];
                v[k][c[k][0]]=T2[k][i];
            }
            else
            {
                int now=c[k][0];
                for(int j=1; j<=now; ++j)
                {
                    c[k][++c[k][0]]=c[k][j]+T1[k][i];
                    v[k][c[k][0]]=v[k][j]+T2[k][i];
                }
            }
        }
    }
    for(int k=1; k<=N; ++k)
    {
        for(int j=V; j>=0; --j)
        {
            for(int i=1; i<=c[k][0]; ++i)//第k组第i种方案
            {
                if(j>=c[k][i])
                    F[j]=max(F[j],F[j-c[k][i]]+v[k][i]);
            }
        }
    }
    printf("%d",F[V]);
    return 0;
}

 

posted @ 2019-10-25 18:54  星空泪  阅读(240)  评论(0编辑  收藏  举报