日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

专题——背包问题

發布時間:2023/12/18 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 专题——背包问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  在這個專題,我為大家帶來了一個動態規劃中的經典得不能再經典的問題——背包問題,在這個專題我打算講三類背包問題:01背包、完全背包、多重背包。廢話不多說,那我就開始講解吧O(∩_∩)O~!

01背包問題:

有n個物品,每個物品的重量為weight[i],每個物品的價值為value[i]。現在有一個背包,它所能容納的重量為total,問:當你面對這么多有價值的物品時,你的背包所能帶走的最大價值是多少?

思路:每個物品無非是裝入背包或者不裝入背包,那么就一個一個物品陸續放入背包中,可以有:狀態轉移方程:

tab[i][j] = max(tab[i-1][j-weight[i]]+value[i],tab[i-1][j]) ({i,j|0<i<=n,0<=j<=total})

其中i表示放第i個物品,j表示背包所容納的重量,那么tab[i-1][j-weight[i]]+value[i]表示放入第i物品,剛開始接觸會有疑問,tab[i-1][j-weight[i]]這個值,可以這樣理解:tab[i-1][j]為裝到上一個物品在背包j容量時的最佳值,那么如果我要求在j容量的時候放入現在的i物品的價值,那么是不是要先得到容量為(j-weight[i])時候的價值,即先得到tab[i-1][j-weight[i]],所以 tab[i-1][j-weight[i]]+value[i] 為放入第i物品的價值; tab[i-1][j] 就是不放入第i個物品

動態規劃的思維就在這里體現了,即tab[i-1][j]是tab[i][j]的最優解(我覺得上面的思路講解較容易理解)。

例子:5個物品,(重量,價值)分別為:(5,12),(4,3),(7,10),(2,3),(6,6)。

故有:

1 for i=[weight[0],total] 2 tab[n-1][i]=weight[0]; //n為物品數量 3 for i=[1,n) 4 for j=[weight[i],total] 5 tab[n-i-1][j]= max(tab[n-i][j-weight[i]]+value[i],tab[n-i][j]) 6 /* print tab[0][total] */

完全背包問題:

有n種物品,每種物品有無限個,每個物品的重量為weight[i],每個物品的價值為value[i]?,F在有一個背包,它所能容納的重量為total,問:當你面對這么多有價值的物品時,你的背包所能帶走的最大價值是多少?

有了上面01背包的式子,這題會變的容易理解很多,只是這個式子要有小小的改動。01背包在二維數組上操作,就是為了防止一個物品被放入多次的情況。因此一維數組可以滿足完全背包的問題。如下:

tab[j] = max(tab[j-weight[i]]+value[i],tab[j]);({i,j|0<i<=n,0<=j<=total})

根本就是一樣的,只不過物品可以被放多次。

故有:

1 for i=[0,n) 2 for(j=weight[i];j<=total;j++) 3 tab[j]=max(tab[j-weight[i]]+value[i],tab[j]) 4 /* print tab[0][total] */

多重背包問題:

有n種物品,每種物品有amount[i]個,每個物品的重量為weight[i],每個物品的價值為value[i]?,F在有一個背包,它所能容納的重量為total,問:當你面對這么多有價值的物品時,你的背包所能帶走的最大價值是多少?

多重和完全更接近,多了數量的限制,用一個count[n]計數數組來限制物品i的數量。當放入第i個物品是較優值的時候,count[i]=count[j-weight[i]]+1)j 的含義請查看代碼);這樣做是因為,放入第i個物品的操作是基于count[j-weight[i]]放入的,所以當count[i-weight[i]]>=amount[i]時,就要阻止放入即便放入第i個物品是較優值。

故有:

1 for i=[0,n) /*將count數組清零*/ 2 for(j=weight[i];j<=total;j++) 3 if(count[j-weight[i]]<amout[i]) 4 tab[j]=max(tab[j-weight[i]]+value[i],tab[j]); 5 if(tab[j]=tab[j-weight[i]]+value[i]) 6 //決定放入i是較優解 7 count[i]=count[j-weight[i]]+1 8 else if(tab[j]=0) //防止裝第1個物品和裝其他物品的情況 9 tab[j]=tab[j-1],count[j]=count[j-1] 10 else count[j]=count[j-1] 11 /* print tab[0][total] */

?

轉載于:https://www.cnblogs.com/geek-007/p/6749688.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的专题——背包问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。