描述: 森炊今天沒吃藥很開森,家裡購置的新房就要領鑰匙了,新房裡有一間他自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說:“你的房間需要購買哪些物品,怎麼佈置,你說了算,只要不超過N元錢就行”。今天一早,森炊就開始做預算了,他把想買的物品分為兩類:主件與附件,附件是從屬於某個主件的,下表就是一 ...
描述:
森炊今天沒吃藥很開森,家裡購置的新房就要領鑰匙了,新房裡有一間他自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說:“你的房間需要購買哪些物品,怎麼佈置,你說了算,只要不超過N元錢就行”。今天一早,森炊就開始做預算了,他把想買的物品分為兩類:主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子:
主件 附件
電腦 印表機,掃描儀
書櫃 圖書
書桌 臺燈,文具
工作椅 無
如果要買歸類為附件的物品,必須先買該附件所屬的主件。每個主件可以有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]。(其中*為乘號)請你幫助森炊設計一個滿足要求的購物單。
輸入格式:
輸入文件的第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是所屬主件的編號)
輸出格式:
輸出文件只有一個正整數,為不超過總錢數的物品的價格與重要度乘積的總和的最大值
(<200000)。
Sample Input
1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0
Sample Output
2200
分析:
這道題有大坑;;
在這裡 我個大家提個醒(親身經歷 才知道 坑人)
①
看數據:
N M 附
vi wi 0 1
1 2
0 3
0 4
3 5
最後一個物品,它是附件
那麼它的主件是哪個?
是附3那一行的主件,還是附4那一行的主件??
編號是在所有的 主件中編號
還是在所有的 物品中編號??
當然是所有物品中的編號!!
我第一眼就看錯了~~~~~~
②每個主件可以有0個、1個或2個附件。
所以分類背包就OK了。
四種情況:
⒈只用主件;
⒉用主件和1號附件;
⒊用主件和2號附件;
⒋用主件和1,2號附件;
源代碼:
#include<bits/stdc++.h>
//#include<iostream>
using namespace std;
int c,n;
int w[70][70],num,vv,v[70][70],p,sum[70];
bool bo[70]={};
int f[200000],wi;
int main()
{
cin>>c>>n;
for(int i=1;i<=n;i++)
{
cin>>w[0][i]>>vv>>p;
v[0][i]=vv*w[0][i];
if(p!=0)
{
bo[i]=1;
sum[p]++;
v[p][sum[p]]=v[0][i];//第p件物品的第sum件附件的"積";
w[p][sum[p]]=w[0][i];//第p件物品的第sum件附件的"錢".
num++;
}
}
for(int i=1;i<=n;i++)
{
if(bo[i]==0)
if(sum[i]==0)
for(int j=c;j>=w[0][i];j--)
f[j]=max(f[j],f[j-w[0][i]]+v[0][i]);
else if(sum[i]==1)
for(int j=c;j>=w[0][i];j--)
{
f[j]=max(f[j],f[j-w[0][i]]+v[0][i]);
if(j>=w[0][i]+w[i][1])
f[j]=max(f[j],f[j-w[0][i]-w[i][1]]+v[0][i]+v[i][1]);
}
else if(sum[i]==2)
for(int j=c;j>=w[0][i];j--)
{
f[j]=max(f[j],f[j-w[0][i]]+v[0][i]);
if(j>=w[0][i]+w[i][1])
f[j]=max(f[j],f[j-w[0][i]-w[i][1]]+v[0][i]+v[i][1]);
if(j>=w[0][i]+w[i][2])
f[j]=max(f[j],f[j-w[0][i]-w[i][2]]+v[0][i]+v[i][2]);
if(j>=w[0][i]+w[i][2]+w[i][1])
f[j]=max(f[j],f[j-w[0][i]-w[i][2]-w[i][1]]+v[0][i]+v[i][2]+v[i][1]);
}
}
sort(f+1,f+c+1);
cout<<f[c]<<endl;
return 0;
}