題目:
題目描述
哆啦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的...