2006年分割槽聯賽普級組之二 開心的…
阿新 • • 發佈:2019-02-19
Description
金明今天很開心,家裡購置的新房就要領鑰匙了,新房裡有一間他自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說:“你的房間需要購買哪些物品,怎麼佈置,你說了算,只要不超過N
元錢就行”。今天一早金明就開始做預算,但是他想買的東西太多了,肯定會超過媽媽限定的N 元。於是,他把每件物品規定了一個重要度,分為5
等:用整數1~5 表示,第5 等最重要。他還從因特網上查到了每件物品的價格(都是整數元)。他希望在不超過N 元(可以等於N
元)的前提下,使每件物品的價格與重要度的乘積的總和最大。設第j 件物品的價格為v[j],重要度為w[j],共選中了k
件物品,編號依次為,j1,j2,……jk
,則所求的總和為:v[j1]*w[j1]+v[j2]*w[j2]+……+v[jk]*w[jk]
(其中*為乘號)
請你幫助金明設計一個滿足要求的購物單。
Input
輸入的第1
行,為兩個正整數,用一個空格隔開:
N m
(其中N(<30000)表示總錢數,m(<25)為希望購買物品的個數。)
從第2 行到第m+1 行,第j 行給出了編號為j-1的物品的基本資料,每行有2
個非負整數
v p (其中v 表示該物品的價格(v≤10000),p
表示該物品的重要度(1~5))
Output
輸出只有一個正整數,為不超過總錢數的物品的價格與重要度乘積的總和的最大值(<100000000)
Sample Input
Sample Output
f[i,j]表示前i件物品在j元限制下的最大重要度,狀態轉移方程為:
f[i,j]=max{f[i-1,j],f[i-1,j-w[i]],v[i]}
(1<=i<=n,1<=j<=m)
f[n,m]即為所求。 時間複雜度:O(nm)
程式1:
var
n,m,i,j:longint;
f:array[0..25,0..30000]of longint;
w,v:array[0..25]of longint;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
begin
readln(m,n);
for i:=1 to n do
begin
readln(w[i],v[i]);
v[i]:=w[i]*v[i];
end;
for i:=1 to n do
for j:=1 to m do
begin
f[i,j]:=f[i-1,j];
if j>=w[i] then f[i,j]:=max(f[i-1,j],f[i-1,j-w[i]]+v[i]);
end;
writeln(f[n,m]);
end.
解題思路2:f[j]表示上篇解題報告的f[i,j],狀態轉移方程為:
f[j]=max{f[j],f[j-w[i]],v[i]}
(1<=i<=n,m>=j>=0)
f[m]為所求。 時間複雜度:O(nm)
程式2:
var
f,w,v:array[0..30000]of longint;
n,m,i,j:longint;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
begin
readln(m,n);
for i:=1 to n do
begin
readln(w[i],v[i]);
v[i]:=v[i]*w[i];
end;
for i:=1 to n do
for j:=m downto 0 do
if j>=w[i] then f[j]:=max(f[j],f[j-w[i]]+v[i]);
writeln(f[m]);
end.
版權屬於: Chris
轉載時必須以連結形式註明原始出處及本宣告。