最近開始跟隨大佬的腳步學習acm,在學習的過程才發現程式設計不是那麼地簡單的,學好程式設計一定要有好的數學功底才行。最近接觸到動態規劃,然後最基礎的揹包公式就難住了我很久,為此我翻遍了很多大佬的部落格,在網上搜尋了很久再加上自己的頓悟,才有了膽量在此寫下這一篇部落格。
本部落格旨在理解公式,並不會過多的講解揹包其他問題,畢竟我也只是個剛觸及揹包的菜鳥而已。
下面開始講解一下基礎揹包問題。
問題描述
有n件物品和乙個容量為v的揹包。第i件物品的重量是wi],價值是v[i]。求解將哪些物品裝入揹包可使價值總和最大。對於這是乙個動態規劃題,所以解這種題就需要乙個狀態轉移公式,此題公式如下:
f[i][j] = max( f[i-1][j], f[i-1][j-w[i]] + v[i] )
w[i]與v[i]題目中有提到,後面都不詳細解釋了
首先要對f[i][j]這個子問題狀態定義要理解透,即f[i][v]表示前i件物品恰放入乙個容量為v的揹包可以獲得的最大價值。
那麼公式右邊第乙個f[i-1][j]就是表示表示前i-1件物品恰放入乙個容量為v的揹包可以獲得的最大價值。
為什麼f[i][j]有可能等於f[i-1][j]?
第i件物品可以選擇放入或者不放入包中,也就是說f[i-1][j]是指不放第i件物品放到此時包裡,那麼f[i-1][j-w[i]]就是理解成第i件物品要放到包裡了。
j是i的狀態下的揹包容量,那麼i-1下的狀態應該是不放i物的狀態,即j-weight[i]。又問前面f[i-1][j]中為什麼是j而不是(j-weight[i])呢?
上面說過f[i-1][j]這個表示不放第i件物品放到包裡, 那麼i-1狀態 到 i狀態下,揹包的容量不變,假設i-1下的容量是v而i下的是j,原本應該這樣子寫f[i-1][v],但現在只知道j不知道v而又j= v,故寫成了f[i-1][j]。
誤區在j上,f[i-1][j]與f[i-1][j-w[i]]中的j,值看似相同,但是意義就大變了。
公式**
for(int i = 1; i <= n; i++)
}
還可以簡化,第二個for中,j初始值為w[i]即可,自己想想試試吧。
現在為了簡化,f 用一維陣列表示 f[j], 直接給出偽**了,主要是講理解,其他內容自己翻大佬們的吧。
for
i=1..n
forj=v..
0 f[j]=max;
我當初卡死在v為什麼要逆序這一塊,然後我看了乙個大佬的部落格才明悟了。下面講得很囉嗦了,因為是當初理解時,一時興起寫下來的,我也沒去改動了。
首先記住f[j]現在是臨時存值的,因為每次變動i時都會用到v次(姑且理解為用到v次吧,因為j>w[i]這個條件有的用不到v次,但為了方便理解就這樣說了)f陣列在每一輪時都在不斷更新它的值,但由於j,所以是逆序訪問f陣列的,f陣列是有f[v]到f[0]順序換值的,說這麼多廢話幹啥呢?
呵呵,快接近答案了!
當初在i狀態時, 還沒更新的那些f陣列仍然保留在i-1狀態下的值是吧!(這句好好體會,應該不難的)。
而f[j] = max這個公式是(狀態下的f值)<—-(推出)—-(i-1狀態時的f值)。
即,用還沒有更新值、還處於i-1狀態下的靠前的f來更新後面的f的值,這樣就保證了f的值是由i-1狀態推出i狀態。
那麼值必然是從f[0]—->f[v]一路更新下去,而因為公式可知,f的值是由前面的f的值推出來的,而前面的f值早就更新到第i狀態了,你現在是拿i狀態下的值推i狀態下的值,呵呵,不對了吧!
好了我就是這樣理解了這兩個最基本的揹包公式,理解了公式,對後面幾個揹包的演算法有很大幫助。
寫到這裡我也犯暈了,沒有當初初次理解揹包公式的那種神秘的感覺了。不過還沒理解的可以再看幾遍,或者翻翻其他大佬的部落格看看,自己體會一下哈。
在網上翻了很多,但發現很多是直接把一段晦澀難懂的話複製貼上的,搞得頭暈。
我看到客一篇對公式理解很好的部落格,講得特別好,部落格傳送之門
對0 1揹包問題的理解
首先宣告的是這是一篇非常非常基礎的對0 1揹包問題的理解。這兩天看了動態規劃初步,看到了0 1揹包問題。看到這裡的時候感覺理解有點困難。問題簡介 有乙個體積為c的揹包,要往裡面裝n中物品,第i種物品的體積為vi,質量為wi,求出揹包裡面最多能裝下多重的物品。劉汝佳對這個問題的分析是引用了前面的回朔法...
理解揹包問題
揹包問題總共有九種,0 1揹包式所有的基礎,所以首先研究0 1揹包 一 0 1揹包 問題陳述 有n件物品和乙個容量為v的揹包。第i件物品的費用是w,價值是v。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大若。1 動態規劃解決 f i,j 表示在前i件物品中選擇若干件放在承...
對卷積公式的形象理解
被棒打了會覺得疼,一直被打一直疼。我們假設h t h t h t 代表乙個人 比如bob 在受到單位衝擊函式 t delta t t 之後的衝擊響應。則這個衝擊響應可以認為是在單位力衝擊的作用下,bob感受到的疼痛度隨時間的變化關係。我們可以假設bob的疼痛值 假設用x xx表示 等於疼痛度與當時力...