題目描述
金明今天很開心,家裏購置的新房就要領鑰匙了,新房裏有一間他自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說:“你的房間需要購買哪些物品,怎麼佈置,你說了算,只要不超過 NN 元錢就行”。今天一早金明就開始做預算,但是他想買的東西太多了,肯定會超過媽媽限定的 NN 元。於是,他把每件物品規定了一個重要度,分爲 55 等:用整數 1-51−5 表示,第 55 等最重要。他還從因特網上查到了每件物品的價格(都是整數元)。他希望在不超過 NN 元(可以等於 NN 元)的前提下,使每件物品的價格與重要度的乘積的總和最大。
設第 jj 件物品的價格爲 v_[j]v[j] ,重要度爲 w_[j]w[j] ,共選中了 kk 件物品,編號依次爲 j_1,j_2,…,j_kj1,j2,…,jk ,則所求的總和爲:
v_[j_1] \times w_[j_1]+v_[j_2] \times w_[j_2]+ …+v_[j_k] \times w_[j_k]v[j1]×w[j1]+v[j2]×w[j2]+…+v[jk]×w[jk] 。
請你幫助金明設計一個滿足要求的購物單。
輸入輸出格式
輸入格式:第一行,爲 22 個正整數,用一個空格隔開: N mNm (其中 N(<30000)N(<30000) 表示總錢數, m(<25)m(<25) 爲希望購買物品的個數。)
從第 22 行到第 m+1m+1 行,第 jj 行給出了編號爲 j-1j−1 的物品的基本數據,每行有 22 個非負整數 v pvp (其中 vv 表示該物品的價格 (v \le 10000)(v≤10000) , pp 表示該物品的重要度( 1-51−5 )
輸出格式:11 個正整數,爲不超過總錢數的物品的價格與重要度乘積的總和的最大值 (<100000000)(<100000000) 。
輸入輸出樣例
說明
NOIP 2006 普及組 第二題
說明:因爲不需要恰好裝滿,所以初始化爲dp都爲0(如果恰好裝滿,則dp[0]爲0,dp[1]~dp[N]都爲-inf,因爲求的是最大值),典型的01揹包模板題。
代碼:
#include <bits/stdc++.h>
using namespace std;
int v[30],p[30],w[30];
int dp[30010];
int main(){
int N,m;
scanf("%d%d",&N,&m);
for(int i=0;i<=N;i++) dp[i]=0;
for(int i=1;i<=m;i++){
scanf("%d%d",&v[i],&p[i]);
w[i]=v[i]*p[i];
}
for(int i=1;i<=m;i++)
for(int j=N;j>=v[i];j--)
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
printf("%d\n",dp[N]);
return 0;
}