金明的預算方案(codevs 1155)


題目描述  Description

金明今天很開心,家里購置的新房就要領鑰匙了,新房里有一間金明自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說:“你的房間需要購買哪些物品,怎么布置,你說了算,只要不超過N元錢就行”。今天一早,金明就開始做預算了,他把想買的物品分為兩類:主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子:

<dl><dd> <colgroup><col width="66"/> <col width="118"/> </colgroup>

主件

附件

電腦

打印機,掃描儀

書櫃

圖書

書桌

台燈,文具

工作椅

</dd></dl>

如果要買歸類為附件的物品,必須先買該附件所屬的主件。每個主件可以有0個、1個或2個附件。附件不再有從屬於自己的附件。金明想買的東西很多,肯定會超過媽媽限定的N元。於是,他把每件物品規定了一個重要度,分為5等:用整數1~5表示,第5等最重要。他還從因特網上查到了每件物品的價格(都是10元的整數倍)。他希望在不超過N元(可以等於N元)的前提下,使每件物品的價格與重要度的乘積的總和最大。

設第j件物品的價格為v[j],重要度為w[j],共選中了k件物品,編號依次為j1,j2,……,jk,則所求的總和為:

v[j1]*w[j1]+v[j2]*w[j2]+ …+v[jk]*w[jk]。(其中*為乘號)

請你幫助金明設計一個滿足要求的購物單。

輸入描述  Input Description

第1行,為兩個正整數,用一個空格隔開:

N m

(其中N(<32000)表示總錢數,m(<60)為希望購買物品的個數。)

從第2行到第m+1行,第j行給出了編號為j-1的物品的基本數據,每行有3個非負整數

v p q

(其中v表示該物品的價格(v<10000),p表示該物品的重要度(1~5),q表示該物品是主件還是附件。如果q=0,表示該物品為主件,如果q>0,表示該物品為附件,q是所屬主件的編號)

輸出描述  Output Description

只有一個正整數,為不超過總錢數的物品的價格與重要度乘積的總和的最大值(<200000)

樣例輸入  Sample Input

1000 5

800 2 0 

400 5 1

300 5 1

400 3 0

500 2 0

樣例輸出  Sample Output

2200

/*
  預處理稍顯惡心的有依賴性的分組背包 
  剛開始讀錯題了,把附件輸入的物品編號理解成了主件編號,結果無限WA 
*/
#include<cstdio>
#include<iostream>
#include<vector>
#define M 40010
#define N 110
using namespace std;
int f[M],w[N][6],v[N][6],ww[N],vv[N],belong[N],cnt,n,m;
vector<int> g[N];
int read()
{
    char c=getchar();int num=0,flag=1;
    while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();}
    while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
    return flag*num;
}
int main()
{
    m=read();n=read();
    for(int i=1;i<=n;i++)
    {
        int fl;
        ww[i]=read(),vv[i]=read(),fl=read();
        if(!fl) g[++cnt].push_back(i),belong[i]=cnt;
        else g[belong[fl]].push_back(i);
    }
    for(int i=1;i<=cnt;i++)
    {
        int j=g[i].size();
          if(j>=1)
        {
            w[i][2]=ww[g[i][0]];
            v[i][2]=vv[g[i][0]]*ww[g[i][0]];
        }
          if(j>=2)
        {
            w[i][3]=ww[g[i][0]]+ww[g[i][1]];
            v[i][3]=vv[g[i][0]]*ww[g[i][0]]+vv[g[i][1]]*ww[g[i][1]];
        }
          if(j>=3)
          {
              w[i][4]=ww[g[i][0]]+ww[g[i][2]];
              w[i][5]=ww[g[i][0]]+ww[g[i][1]]+ww[g[i][2]];
              v[i][4]=vv[g[i][0]]*ww[g[i][0]]+vv[g[i][2]]*ww[g[i][2]];
              v[i][5]=vv[g[i][0]]*ww[g[i][0]]+vv[g[i][1]]*ww[g[i][1]]+vv[g[i][2]]*ww[g[i][2]];
          }
    }
    for(int i=1;i<=cnt;i++)
      for(int j=m;j>=0;j--)
        for(int k=1;k<=5;k++)
          if(j>=w[i][k])
            f[j]=max(f[j],f[j-w[i][k]]+v[i][k]);
    printf("%d",f[m]);
    return 0;
}
View Code

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com