ACM竞赛学习整理开篇之01背包问题
ACM競(jìng)賽學(xué)習(xí)整理開(kāi)篇之01背包問(wèn)題。
最近,偶然的一次機(jī)會(huì)讓我關(guān)注信息奧賽的一些內(nèi)容。發(fā)現(xiàn)其中的內(nèi)容很有趣,是學(xué)習(xí)編程的一條很好的路徑,又能很好地將數(shù)學(xué)和編程聯(lián)系到一起。在csdn里看到了不少同好也在學(xué)習(xí)ACM競(jìng)賽。于是,決定通過(guò)csdn這個(gè)平臺(tái)來(lái)記錄,我的ACM學(xué)習(xí)之路。
背包問(wèn)題:
背包問(wèn)題已經(jīng)研究了一個(gè)多世紀(jì),早期的作品可追溯到1897年 [1] 數(shù)學(xué)家托比亞斯·丹齊格(Tobias Dantzig,1884-1956)的早期作品 [2] ,并指的是包裝你最有價(jià)值或有用的物品而不會(huì)超載你的行李的常見(jiàn)問(wèn)題。
背包問(wèn)題的應(yīng)用:
1998年的石溪布魯克大學(xué)算法庫(kù)的研究表明,在75個(gè)算法問(wèn)題中,背包問(wèn)題是第18個(gè)最受歡迎,第4個(gè)最需要解決的問(wèn)題(前三為后kd樹(shù),后綴樹(shù)和bin包裝問(wèn)題)。
背包問(wèn)題出現(xiàn)在各種領(lǐng)域的現(xiàn)實(shí)世界的決策過(guò)程中,例如尋找最少浪費(fèi)的方式來(lái)削減原材料, [4] 選擇投資和投資組合, [5] 選擇資產(chǎn)支持資產(chǎn)證券化 [6] ,和生成密鑰為Merkle-Hellman [7] 和其他背包密碼系統(tǒng)。
在ACM競(jìng)賽中設(shè)計(jì)的背包問(wèn)題有:
先了解下3種簡(jiǎn)單的背包概念:
0-1背包 (ZeroOnePack): 有N件物品和一個(gè)容量為V的背包。每種物品均只有一件 第i件物品的費(fèi)用是c[i],價(jià)值是w[i]。求解將哪些物品裝入背包可使價(jià)值總和最大。
完全背包(CompletePack): 有N種物品和一個(gè)容量為V的背包,每種物品都有無(wú)限件可用。第i種物品的費(fèi)用是c[i],價(jià)值是w[i]。求解將哪些物品裝入背包可使這些物品的費(fèi)用總和不超過(guò)背包容量,且價(jià)值總和最大。
多重背包 (MultiplePack): 有N種物品和一個(gè)容量為V的背包。第i種物品最多有n[i]件可用, 每件費(fèi)用是c[i],價(jià)值是w[i]。求解將哪些物品裝入背包可使這些物品的費(fèi)用總和不超過(guò)背包容量,且價(jià)值總和最大。*
比較三個(gè)題概念,會(huì)發(fā)現(xiàn)不同點(diǎn)在于每種背包的數(shù)量,01背包是每種只有一件,完全背包是每種無(wú)限件,而多重背包是每種有限件。
**
01 背包
1、OJ 例題
【例題】
有n個(gè)物品,編號(hào)為i的物品的重量為w[i],價(jià)值為c[i],現(xiàn)在要從這些物品中選一些物品裝到一個(gè)容量為m的背包中,使得背包內(nèi)物體在總重量不超過(guò)m的前提下價(jià)值盡量大。
【輸入】
第1行:兩個(gè)整數(shù),n(物品數(shù)量,n≤3500)和m(背包容量,m≤12880)。
第2…n+1行::每行二個(gè)整數(shù)w[i],c[i],表示每個(gè)物品的重量和價(jià)值。
【輸出】
僅一行,一個(gè)數(shù),表示最大總價(jià)值。
【輸入樣例】
4 6
1 4
2 6
3 12
2 7
【輸出樣例】
23
2、 解題思路:
用動(dòng)態(tài)規(guī)劃的思路,階段就是“物品的件數(shù)”,狀態(tài)就是“背包剩下的容量”,那么很顯然f [ i , v ] 就設(shè)為從前 i 件物品中選擇放入容量為 v 的背包最大的價(jià)值。那么狀態(tài)轉(zhuǎn)移方程為:
f[i][v]=max{ f[i-1][v],f[i-1][v-w[i]]+val[i] }。把這個(gè)過(guò)程理解下:在前i件物品放進(jìn)容量v的背包時(shí),
它有兩種情況:
第一種是第i件不放進(jìn)去,這時(shí)所得價(jià)值為:f[i-1][v]
第二種是第i件放進(jìn)去,這時(shí)所得價(jià)值為:f[i-1][v-w[i]]+val[i]
(第二種是什么意思?就是如果第i件放進(jìn)去,那么在容量v-w[i]里就要放進(jìn)前i-1件物品)
最后比較第一種與第二種所得價(jià)值的大小,哪種相對(duì)大,f[i][v]的值就是哪種。
(這是基礎(chǔ),要理解!)
3、 代碼求解:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<string> #include<cstdlib> #include<queue> #include<vector> #define INF 0x3f3f3f3f #define PI acos(-1.0) #define N 1001 #define MOD 2520 #define E 1e-12 using namespace std; int m,n; int w[N],c[N],f[N];void ZeroOnePack(int cost,int weight) {for(int v=m;v>=weight;v--){f[v]=max(f[v],f[v-weight]+cost);cout<<"f["<<v<<"]"<<"="<<f[v]<<" ";}cout<<endl; }int main() {cin>>m>>n;for(int i=1;i<=n;i++)cin>>w[i]>>c[i];cout<<endl;for(int i=1;i<=n;i++)ZeroOnePack(c[i],w[i]);cout<<"max="<<f[m]<<endl;return 0; }4、結(jié)果輸出
5、反思總結(jié)
背包問(wèn)題是貪心算法的實(shí)例,可以根據(jù)動(dòng)態(tài)規(guī)劃解題步驟來(lái)實(shí)現(xiàn)
(問(wèn)題抽象化、建立模型、尋找約束條件、判斷是否滿足最優(yōu)性原理、找大問(wèn)題與小問(wèn)題的遞推關(guān)系式、填表、尋找解組成)找出01背包問(wèn)題的最優(yōu)解以及解組成,然后編寫(xiě)代碼實(shí)現(xiàn)。
回顧01背包的定義:
PS:學(xué)習(xí)的心得比較難寫(xiě),我將代碼放到了C-free開(kāi)發(fā)環(huán)境中試驗(yàn)了下,然后把計(jì)算的結(jié)果打印在了屏幕上,然后草稿紙上將其步驟再簡(jiǎn)單畫(huà)了畫(huà),最后在網(wǎng)上查找了相關(guān)的內(nèi)容來(lái)幫助理解,以上內(nèi)容,基本上還是復(fù)制粘貼,等后續(xù)實(shí)際問(wèn)題再操練吧。
這里有杭電OJ上的一道例題供大家參考:
題目:http://acm.hdu.edu.cn/showproblem.php?pid=2602
代碼:http://www.wutianqi.com/?p=533
參考文檔:
1、https://blog.csdn.net/weixin_41162823/article/details/87878853背包問(wèn)題-筆記整理
2、https://blog.csdn.net/qq_37767455/article/details/9908667801背包問(wèn)題 圖解+詳細(xì)解析
3、http://www.wutianqi.com/blog/539.html背包之01背包、完全背包、多重背包詳解
4、https://blog.csdn.net/chanmufeng/article/details/82955730徹底理解0-1背包問(wèn)題
總結(jié)
以上是生活随笔為你收集整理的ACM竞赛学习整理开篇之01背包问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Qt TCP 通讯简单案例
- 下一篇: ACM竞赛学习整理--矩阵运算