關於偉大的dp,入門便是從揹包問題開始,沒錯,揹包分為01揹包,完全揹包,多重揹包等。
眾所周知完全揹包便是01揹包的反向思想,那麼什麼是01揹包?沒錯01揹包,顧名思義0和1(廢話),就是選(1)和不選(0)。
有一大堆東西(n件),有價值(v),有重量(w),有乙個承重(v)的揹包,嗯沒錯,跟貪心差不多,求可以裝到的西的價值之和最大。
現在定義f陣列,f[i]表示重量為i的揹包(陣列下標)能裝到的最大價值,那麼我們要求的答案就是f[v]。
為何如此定義?
因為動歸的思想就是從子問題(小問題)下手,解決子問題再解決大一點的子問題,解決大一點的子問題,就解決更大的子問題從而解決整個問題。
好比寫文章,你得先學拼音,再習識字,再學習寫字,再學習構思,再開始寫文章。
如何求f[i]呢?我們不妨列舉每乙個物品。
嗯,那麼第乙個for就出來了。
for(int i=1;i<=n;i++)
嗯,真香。
然後呢列舉能裝下這個物品的全部揹包。
for(int j=v;j>=v[i];j--)
嗯,然後計算揹包能裝下的物品的最大價值之和。
f[j]=max(f[j],f[j-w[i]]+v[i]);
顧名思義前者,f[j]就是不選這個東西。
後者f[j-w[i]]+v[i]便是選這個東西,+v[i]眾所周知選這個物品就要加上他的價值。
那麼j-w[i]是何意義呢?
嗯沒錯j指重量j,w[i]指這個物品的重量。
在當前情況下我們不知道揹包夠不夠裝這個物品,所以我們必須要騰出w[i]的空間來裝這個物品。
那麼f[j-w[i]]在這裡表示的是,我騰出空間(丟掉一些東西)時可獲得的最大價值。
所以核心部分便是:
for(int i=1;i<=n;i++)for(int j=v;j>=v[i];j--)
f[j]=max(f[j],f[j-w[i]]+v[i]);
然後呢
printf("%d\n
",f[v]);
大功告成!
揹包問題 01揹包問題
n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...
揹包問題 01揹包
有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。01揹包中的 01 就是一種物品只有1件,你可以選擇放進去揹包即1,也可以選擇不放入揹包中即0。include include using namespace std const int ...
揹包問題(01揹包)
1085 揹包問題 在n件物品取出若干件放在容量為w的揹包裡,每件物品的體積為w1,w2 wn wi為整數 與之相對應的價值為p1,p2 pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物品的數量,w為揹包的容量。1 n 100,1 w 10000...