動態規劃的兩個經典問題 01揹包

2021-05-06 17:30:11 字數 1992 閱讀 6602

"學動態規劃要從經典問題開始"

--by lrj

答應了小q要寫這個的.......哎......

先說那個什麼01揹包.....

為什麼叫揹包呢?因為這些問題的原型是說有很多東西,每個東西都有體積,也有價值,你要去春遊,要選一些東西放到揹包裡.問題是要怎麼選才能在總體積不超過揹包的體積的前提下,讓總價值最大.

為什麼是0/1呢?因為每種東西都不一樣(每個東西的體積和價值都不一樣),你要拿就拿,不拿拉到,就2種選擇,不能拿半個,也不能拿2個(因為每種東西只有乙個)...所以叫01.

(其實揹包問題不一定只能拿乙個,這裡說的是揹包問題的一種--01揹包).

所以,0/1揹包其實就是決定每個東西拿不拿了.

那麼,"拿"這個動詞怎麼表示呢?不是你把手伸出去伸回來就完了.要考慮在演算法裡面"拿"的意義.一旦"拿"了乙個東西,那麼,總的體積會增加這個東西的體積,總的價值也會增加這個東西的價值.

用f[k]表示當總體積為k的時候物品的總價值.

如果不拿這個東西,f[k]就等於f[k],如果要拿這個東西.....怎麼辦呢?總的體積k是確定的,那麼拿了這個東西過後的總價值等於拿這個東西之前的總價值加上這個東西的價值,拿這個東西之前的總價值是多少呢?既然拿了過後總體積是k,那麼拿之前的體積就是(k-拿的物品的體積),所以拿之前的價值是f[k-當前物品的體積],所以"拿"這個動作,就表現為:f[k]=f[k-當前物品的體積]+當前物品的價值.而要最後最大,所以~~~~就選2者中最大的.....

也就是:f[k]=max

ok了~~~~~~然後每種物品列舉一次....

在寫的時候,有一些細節,就是計算f[k]的時候,要從大到小迴圈回來...為什麼呢?

比如,設迴圈的時候k取過k1,k2,k3三個值,物品中有乙個體積為v1的物品,而且k3-k2=k2-k1=v1,如果從小到大迴圈,在計算的時候就會出現"f[k2]是由f[k1]加上體積為v1的物品的價值得到,而f[k3]又是由f[k2]加上體積為v1的物品的價值得到",這就是說--這個體積為v1的物品被取了2次!!!!所以不行咯~~~~~~

0/1揹包在noip中有這些題:noip2005普及組第3題"採藥"(這個題是原封不動的0/1揹包),noip2006普及組第二題"開心的金明" (幾乎原封不動),noip2001普及組"裝箱問題"(這個也可以看作揹包的,只是小變形了一下),noip2006提高組第二題"金明的預算方案" (很bt的變形,這裡略去)

noip2005普及組第3題"採藥":http://www.vijos.cn/problem_show.asp?id=1104

完全不需要修改的0/1揹包:把採藥時間看作體積,藥的價值為價值.

我的c++程式(螢幕輸入輸出):

#include

#include

using namespace std;

int max(int a,int b)

int main()

*me;     

me=new medic[m];

for(int k=0;k=me[j].time;k--)/*計算,注意要k>=me[j].time才能保證k-me[j].time>0 */

}int max=0;

for(int k=0;k<=t;k++)/*這裡不用這麼寫,直接輸出c[t]就可以了,我寫的時候受hyf牛的影響寫複雜了 */

cout<

#include

int main()

;long long *money=new long long [c+1];

for(int k=0;k<=c;k++)money[k]=0;

object *obj;

obj=new object [m];

for(int k=0;k=obj[j].cost;k--)

}printf("%d",v-b[v]);

system("pause");

return 0;

}就說這麼多了....

還是lrj的一句話"動態規劃真的需要思維很靈活,需要靈感"    

我的思維就不靈活,也沒靈感...

經典動態規劃問題 0 1揹包問題

乙個揹包有一定的承重cap,有n件物品,每件都有自己的價值,記錄在陣列v中,也都有自己的重量,記錄在陣列w中,每件物品只能選擇要裝入揹包還是不裝入揹包,要求在不超過揹包承重的前提下,選出物品的總價值最大。每個物品只有1個,給定物品的重量w價值v及物品數n和承重cap。請返回最大總價值。狀態 dp i...

動態規劃經典問題 01揹包問題

分解為子問題,尋找子問題間的依賴關係。第二行 肯定不選擇物品i 第三行 進行判斷是否選擇物品i。偽 用動態規劃解決揹包問題 public class backbag 填表 for int i 1 i n i else return opt n capacity return opt public s...

動態規劃揹包問題 01揹包

問題描述 n種物品,每種乙個。第i種物品的體積為vi,重量為wi。選一些物品裝到容量為c的揹包,使得揹包內物品不超過c的前提下,重量最大。問題分析 宣告乙個f n c 的陣列。f i j 表示把前i件物品都裝到容量為j的揹包所獲得的最大重量。當 j v i 時,揹包容量不足以放下第 i 件物品,f ...