金明今天很開心,家裡購置的新房就要領鑰匙了,新房裡有一間金明自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說:「你的房間需要購買哪些物品,怎麼布置,你說了算,只要不超過
n元錢就行」。今天一早,金明就開始做預算了,他把想買的物品分為兩類:主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子:
主件 附件
電腦 印表機,掃瞄器 書櫃
圖書 書桌
檯燈,文具
工作椅 無
如果要買歸類為附件的物品,必須先買該附件所屬的主件。每個主件可以有0個、
1個或2個附件。附件不再有從屬於自己的附件。金明想買的東西很多,肯定會超過媽媽限定的
n元。於是,他把每件物品規定了乙個重要度,分為
5等:用整數1~
5表示,第
5等最重要。他還從網際網路上查到了每件物品的**(都是
10元的整數倍)。他希望在不超過
n元(可以等於
n元)的前提下,使每件物品的**與重要度的乘積的總和最大。 設第
j件物品的**為
v[j]
,重要度為
w[j]
,共選中了
k件物品,編號依次為j1
,j2,……,jk
,則所求的總和為:
v[j1]*w[j
1]+v[j
2]*w[j
2]+
…+v[j
k]*w[jk]
。(其中
*為乘號)
請你幫助金明設計乙個滿足要求的購物單。
分析:這一道題中給出了物品的**和重要度,就很容易看出這道題的解法是組合揹包了(甚至可以說是一道組合揹包的模板題==)。
動態轉移方程:01揹包,完全揹包:f[i,j]:=max(f[i,j-w[i]]+v[j])(就是一樣的動態轉移方程,就不多解釋了)
const
maxn=100;
maxm=1000;
vara:array[0..maxn,0..5] of longint;
f:array[0..maxm*30] of longint;
w,c,p:array[0..maxn] of longint;
n,m,v:longint;
function max(x,y:longint):longint;
begin
if x>y then
exit(x)
else
exit(y);
end;
procedure init;
vart:array[1..maxm,0..5] of longint;
o,p1,q:array[1..maxm] of longint;
i,j,k:longint;
begin
readln(m,n);
k:=0;
for i:=1 to n do
begin
readln(o[i],p1[i],q[i]);
if q[i]=0 then
begin
inc(k);
t[k,0]:=1;
t[k,1]:=i;
p[i]:=k;
end;
end;
for i:=1 to n do
if (q[i]<>0) then
begin
inc(t[p[q[i]],0]);
t[p[q[i]],t[p[q[i]],0]]:=i;
p[i]:=p[q[i]];
end;
j:=0;
for i:=1 to k do
case t[i,0] of
1:begin
inc(j);
w[j]:=o[t[i,1]];c[j]:=p1[t[i,1]];c[j]:=c[j]*w[j];
inc(a[i,0]);a[i,a[i,0]]:=j;
end;
2:begin
inc(j);
w[j]:=o[t[i,1]];c[j]:=p1[t[i,1]];c[j]:=c[j]*w[j];
inc(a[i,0]);a[i,a[i,0]]:=j;
inc(j);w[j]:=o[t[i,1]]+o[t[i,2]];
c[j]:=p1[t[i,1]]*o[t[i,1]]+p1[t[i,2]]*o[t[i,2]];
inc(a[i,0]);a[i,a[i,0]]:=j;
end;
3:begin
inc(j);
w[j]:=o[t[i,1]];c[j]:=p1[t[i,1]];c[j]:=c[j]*w[j];
inc(a[i,0]);a[i,a[i,0]]:=j;inc(j);
w[j]:=o[t[i,1]]+o[t[i,2]];c[j]:=p1[t[i,1]]*o[t[i,1]]+p1[t[i,2]]*o[t[i,2]];
inc(a[i,0]);a[i,a[i,0]]:=j;inc(j);w[j]:=o[t[i,1]]+o[t[i,3]];
c[j]:=p1[t[i,1]]*o[t[i,1]]+p1[t[i,3]]*o[t[i,3]];inc(a[i,0]);
a[i,a[i,0]]:=j;inc(j);w[j]:=o[t[i,1]]+o[t[i,2]]+o[t[i,3]];
c[j]:=p1[t[i,1]]*o[t[i,1]]+p1[t[i,2]]*o[t[i,2]]+p1[t[i,3]]*o[t[i,3]];
inc(a[i,0]);a[i,a[i,0]]:=j;
end;
end;
v:=k;
n:=j;
end;
procedure main;
vari,j,k:longint;
begin
for k:=1 to v do
for j:=m downto 0 do
for i:=1 to 4 do
if (j>=w[a[k,i]]) and (a[k,i]<>0) then
f[j]:=max(f[j],f[j-w[a[k,i]]]+c[a[k,i]]);
write(f[m]);
end;
begin
init;
main;
end.
動態規劃 金明的預算方案
題目傳送門 題目描述 金明今天很開心,家裡購置的新房就要領鑰匙了,新房裡有一間金明自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說 你的房間需要購買哪些物品,怎麼布置,你說了算,只要不超過n元錢就行 今天一早,金明就開始做預算了,他把想買的物品分為兩類 主件與附件,附件是從屬於某個主件的,下表...
問題 1175 金明的預算方案 動態規劃
時間限制 1sec 記憶體限制 128mb 金明今天很開心,家裡購置的新房就要領鑰匙了,新房裡有一間金明自己專用 的很寬敞的房間。更讓他高興的是,媽媽昨天對他說 你的房間需要購買哪些物品,怎麼布置,你說了算,只要不超過n元錢就行 今天一早,金明就開始做預 算了,他把想買的物品分為兩類 主件與附件,附...
金明的預算
金明的預算方案 題目描述 金明今天很開心,家裡購置的新房就要領鑰匙了,新房裡有一間金明自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說 你的房間需要購買哪些物品,怎麼布置,你說了算,只要不超過n元錢就行 今天一早,金明就開始做預算了,他把想買的物品分為兩類 主件與附件,附件是從屬於某個主件的,...