開心的金明(01揹包)

題目描述

金明今天很開心,家裏購置的新房就要領鑰匙了,新房裏有一間他自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說:“你的房間需要購買哪些物品,怎麼佈置,你說了算,只要不超過 NN 元錢就行”。今天一早金明就開始做預算,但是他想買的東西太多了,肯定會超過媽媽限定的 NN 元。於是,他把每件物品規定了一個重要度,分爲 55 等:用整數 1-515 表示,第 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-1j1 的物品的基本數據,每行有 22 個非負整數 v pvp (其中 vv 表示該物品的價格 (v \le 10000)(v10000) , pp 表示該物品的重要度( 1-515 )

輸出格式:

11 個正整數,爲不超過總錢數的物品的價格與重要度乘積的總和的最大值 (<100000000)(<100000000) 。

輸入輸出樣例

輸入樣例#1: 複製
1000 5
800 2
400 5
300 5
400 3
200 2
輸出樣例#1: 複製
3900

說明

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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章