01背包(修订版)
由于時間比較充裕,重新修訂一部分。
這次把一些補充的放進來,其他的基礎說明見后半部分
這些一共說明:01背包、完全背包、多重背包 ?將會詳細說明。
三種背包混合、二維背包、分組背包、依賴背包、泛化背包 將大致說明。
?
01背包
如上次說明一般,這次提一下優化和其他說明
首先我做01背包的思路的是在背包價值固定的情況下,不斷遍歷增加物品,獲取當前背包容量下課存放的最大價值
同時也有另一種做法:物品固定,遍歷背包大小,獲取該物品存放與否對總價值的影響。
后一種肯能優化更高一點 但不會太多,兩者復雜度都是O(VN)
其中時間復雜度無法優化,但空間復雜度可以進行簡單優化到O(N)
因為創建二維數組的目的是為了記錄中間變量,每次記錄當前行的值,下一次循環的時候與上一次的值進行比較。
那么就可以優化為以為一維數組,數組記錄當前行的值,下一次循環的時候倒序判斷,因為每次判斷的值是上一行對應的值和上一行列數靠前的值加上物品的價值。
倒序遍歷的時候可以把值進行覆蓋更新,以便以后多次更新利用。
下面放上代碼吧:
1 For(int i= 0, i<N; i++ ){ 2 for(int j = U; j>Ti; j--}{ 3 F[j] = Max(F[j], f[j-Ti]+Vi) 4 } 5 }同樣的需要進行初始化賦值。
這里提一下,之前以為賦值為0就好了,后來發現在大神們的思想里又對問題進行了細分
包括1.只求出最大價值,不要求必須袋子放滿 ?2.恰好裝滿背包時最大價值
是不是感受到大神們滿滿的惡意
下面用原話來進行解釋(我怕我解釋不清楚)
我們看到的求最優解的背包問題題目中,事實上有兩種不太相同的問法。有的題目
要求“恰好裝滿背包”時的最優解,有的題目則并沒有要求必須把背包裝滿。一種區別
這兩種問法的實現方法是在初始化的時候有所不同。
如果是第一種問法,要求恰好裝滿背包,那么在初始化時除了F[0] 為0,其它
F[1::V ] 均設為?1,這樣就可以保證最終得到的F[V ] 是一種恰好裝滿背包的最優解。
如果并沒有要求必須把背包裝滿,而是只希望價格盡量大,初始化時應該將F[0::V ]
全部設為0。
這是為什么呢?可以這樣理解:初始化的F 數組事實上就是在沒有任何物品可以放
入背包時的合法狀態。如果要求背包恰好裝滿,那么此時只有容量為0 的背包可以在什
么也不裝且價值為0 的情況下被“恰好裝滿”,其它容量的背包均沒有合法的解,屬于
未定義的狀態,應該被賦值為-∞ 了。如果背包并非必須被裝滿,那么任何容量的背包
都有一個合法解“什么都不裝”,這個解的價值為0,所以初始時狀態的值也就全部為0
了。
?
完全背包
下面說一下完全背包,完全背包就是說物品的個數無限個,可以重復放置
這樣就要求比較的時候不能與上一個相比,于是狀態轉移方程式就改為與當前行進行比較
valueData[i][j] = Max(valueData[i-1][j], valueData[i][j-weight[z]]+value[z]);與01背包的區別是
因為物品存放無個數限制,完全可以多次放置,所以比較對象是當前物品放置歷史最優值和不放置當前物品。
如此則完成完全背包的實現。
同樣的 ?完全背包也可以進行空間復雜度的優化,原理與01背包相同。
?
多重背包
?多重背包的定義是物品個數有限個,并且說明當前物品個數。
狀態轉移方程式
1 valueData[i][j] = Max ( valueData[i-1][j - k*weight[i]] +k*value[i] ) 0<=k<=num[i]解釋起來就是物品放置個數內求出最大價值
?
?
?混合三種背包
字面意思,三種背包都存在的混合體,有的物品只有一個(01背包),有的物品無限多個(完全背包)
有的物品有限多個(多重背包),這是可以將問題劃為三分,分別把之前的背包封裝起來,判斷物品是哪一類分別調用不同的方法
最終求得最優解
二維背包
物品的屬性有兩個,要同時滿足才可放進去,例如袋子存放物品既要考慮物品體積也要考慮物品重量
對應解決辦法是創建的數組也增加維度,
詳細的。。。。。不會
分組背包
意思多個物品被分組,且分組內物品相互排斥,只能取出一個
詳細。。。。。不會
泛化背包
意思是物品沒有固定價值和質量,物品的價值和質量隨著分配的空間變化 ,。。。。。。不會
感覺就像液體水一樣,好幾種水,每個都是泛化對象,但又感覺不會這么簡單。。。是在搞不懂大神們是怎么思考問題的
? OVER
背包問題說起來就是不斷的在基礎上提出新的問題,再不斷解決、不斷提問題
然后大神們津津樂道,我卻瘋掉了。。
?
?
以下是上次分享的內容
第一次分享,并不知道該拿出些什么,之前學的算法好像都還回去了。
最后祭出了背包,可是背包九講又不全會,于是拿出了最簡單的01背包。
話說。。。。01背包也忘了
開始復習ing。
?
1.01背包
首先01背包是對一個有固定容積的“”盒子“”進行物品存放,有N個物品,
每個物品的價值、體積分別是V1/T1、V2/T2、、、Vn/Tn。
需要求出能存放的最大價值。
按照固有思想,肯定放置性價比最高的,但是存在容積不匹配的情況
隨便一個反例,有一個價值10、體積5和一個價值1體積1的物品,放在容量為4的袋子中。
如果選擇倒推,則變成了暴力搜索了,時間復雜度就變大了。
?
在此基礎上,機智的前輩們用貪心思想,加上動態規劃完成了01背包。
將一個大問題的最優解,分解成一堆堆小問題的最優解,
要求得能放置的最大價值,對于每個物品求出放與不放的最優解。
例如對第i個物品,在能夠放置的前提下,求出放這個物品和不放這個物品的最優值。
得到狀態轉移方程式:
F[i][j] = Max(F[i-1][j], F[i-1][j-Ti]+Vi);
舉例說明:
兩個0的初始化是為了放置數組越界出現異常。
完全背包、多重背包的拓展
完全背包:在01背包的基礎上,每個物品可以無限制存放個數。
狀態轉移方程式改成與F[i][j-Ti]+Vi。
多重背包:在01背包基礎上,每個物品可以放置有限次數且不固定。
01背包中存在價值體積相同的物品,可以轉化為01背包思考。
剩下的幾種,不會。。。。
轉載于:https://www.cnblogs.com/yishilin/p/8397737.html
總結
- 上一篇: fastJson去掉指定字段
- 下一篇: Django知识总结(一)