dp 01揹包求方案 195 Buyer

2021-10-06 08:29:41 字數 1435 閱讀 4190

題目:

題目描述

哆啦a夢班級舉辦個party,當然吃的東西必不可少,哆啦a夢負責採購任務,他得到了乙份清單,上面註明不同食品的受歡迎程度,哆啦a夢需要用一定的價錢盡可能達到的更大的受歡迎程度!例如,瓜子的受歡迎程度為20,瓜子的價錢是50元,那麼如果哆啦a夢選擇買瓜子,將花費50元,但受歡迎程度增加了20。為了避免食品單調性,每種食品只能買乙份,不能重複購買。 現在哆啦a夢需要知道如何採購才能達到最大的受歡迎程度,你能幫助他嗎?

輸入輸入資料為多組,每組輸入的第一行有兩個正整數m和n(m<100&&n<1000),分別為哆啦a夢可以支配的錢數和清單上的可選擇的物品種類。 接下來的n行每行有兩個正整數,分別為每種物品的價錢和它的受歡迎程度(編號為1到n)。

輸出如果存在物品購買,那麼輸出的第一行為能夠達到的最大的受歡迎程度。第二行為需要購買的物品的編號(如果有多種可能,輸出字典序靠前的那種),空格分隔每個數字;如沒有物品可以購買,輸出只有一行,為數字0。

樣例輸入

10 4

100 5

5 55 5

10 10

樣例輸出

102 3

說明:

因為求具體的方案,我們就不能採取之前滾動陣列優化版本的 01揹包 ,因為這樣會損失一些具體方案

因為要求字典序最小,那麼我們肯定採取貪心策略(能選序號小的就選序號小的)

我們如果從前往後遍歷所有的物品,那麼最後 dp[n][m] 就是最後答案,那我們就得從後往前遍歷才可以求的具體方案 ,但是這樣所求的是字典序最大的

所以我們應該反一下,從後往前去遍歷所有物品,這樣dp[1][m]就是最後答案,那麼我們就從前往後遍歷就可以求具體方案,這樣求的是字典序最小的

**:

#include

using namespace std;

const

int maxn=

1005

;const

int maxm=

105;

int m,n;

int w[maxn]

,v[maxn]

,dp[maxn]

[maxm]

;void

solve()

}for

(int i=

1;i<=n;i++

)for

(int i=n;i>=

1;i--

)else}}

if(dp[1]

[m])

else

}void

print()

} s=m;

for(

int i=

1;i<=n;i++)}

}int

main()

return0;

}

演算法筆記 揹包DP (0 1揹包)

1.0 1揹包 參考例題 hloj416採藥 二維解法 我們設f i j 為前i個物品放進容量為j的揹包的最大價值 設體積為v i 價值為w i 我們可以列舉i 1到n 和j 1到n 不難得出狀態轉移方程 f i j max 可以知道,當第i件物品不取時,總價值為f i 1 j 取得話,總價值為前i...

揹包DP(01揹包,多重揹包,完全揹包)

從前乙個轉態轉移過來,選還是不選 for int i 1 i n i else f i j f i 1 j 01揹包優化 滾動陣列 for int i 1 i n i for int j m j 1 j if weight i j f j max f j f j weight i value i 優...

ACM 程式設計競賽 DP 01揹包

輸入 n 4 w,v w 5 輸出 7 選擇0,1,3 暴力演算法 o 2 n include using namespace std const int maxn 100 int w maxn v maxn int n,w int rec int i,int j 從第i個商品開始挑選總重量小於j的...