01揹包問題 空間複雜度o V

2021-07-27 22:59:36 字數 2942 閱讀 7553

**題目**

有n件物品和乙個容量為v的揹包。第i件物品的所需容量是c[i],價值是w[i]。求解將哪些物品裝入揹包可使價值總和最大。

f[i][v]表示前i件物品恰放入乙個容量為v的揹包可以獲得的最大價值。

現在我們來看第i件物品:

---如果選擇將第i件物品放入,那麼在放置前i-1件物品的時候應該空出v-c[i]的容量,此時方程為f[i-1][v-c[i]]+w[i]

---如果選擇不將第i件物品放入,那麼此時的最大價值前第i-1件放入容量為v的揹包獲得的最大價值決定,此時方程為f[i-1][v]

綜上所述,得出f[i][v]

f[i][v]=max
推薦大家走一遍例項,看一下下方結果輸出的**,**懂了,演算法就懂了

假設當前有五件商品(重量,價值)(5,12),(4,3),(7,10),(2,3),(6,6)

揹包容量為15

解決**如下所示

時間複雜度以及空間複雜度均為o(n×v)

#coding=utf-8

class

solution

():def

zero_one

(self,goods,max_v):

f = [[0] * (max_v+1) for i in range(len(goods))]

for v in range(goods[0][0],max_v+1):

f[0][v] = goods[0][1]

for i in range(1,len(goods)):

for v in range(max_v+1):

#注意下面if語句判斷,如果v《當前商品質量,那麼f[i][v]就是f[i-1][v]

if v>=goods[i][0]:

f[i][v] = max(f[i-1][v],f[i-1][v-goods[i][0]]+goods[i][1])

else:

f[i][v] = f[i-1][v]

return f

goods = [[5,12],[4,3],[7,10],[2,3],[6,6]]

test = solution()

print test.zero_one(goods,15)

前n件商品01

2345

6789

1011

1213

141510

0000

1212

1212

1212

1212

1212122

0000

3121212

1215

1515

1515

151530

0003

1212

1212

1515

1522

2222224

0033

3121215

1515

1518

2222

252550

0333

1212

1515

1515

1822

222525

時間複雜度已經無法優化,但是空間複雜度可以優化成o(v)

揹包九講中的解釋如下:

那麼,如果只用乙個陣列f[0..v],能不能保證第i次迴圈結束後f[v]中表示的就是我們定義的狀態f[i][v]呢?f[i][v]是由f[i-1][v]和f[i-1][v-c[i]]兩個子問題遞推而來,能否保證在推f[i][v]時(也即在第i次主迴圈中推f[v]時)能夠得到f[i-1][v]和f[i-1][v-c[i]]的值呢?事實上,這要求在每次主迴圈中我們以v=v..0的順序推f[v],這樣才能保證推f[v]時f[v-c[i]]儲存的是狀態f[i-1][v-c[i]]的值。

個人理解

如果v倒序計算(遍歷)

f[v]=max;

↑   ↖同樣可以理解成i-1取得的結果

可以理解成之前i-1取得的結果

由於v是倒序,所有比v大的表示i層的結果,而≤的是i-1層的結果,計算當前v的只需要前i-1層的結果即可

**如下所示:

class

solution

():def

zero_one

(self,goods,max_v):

f = [0] * (max_v+1)

for i in range(len(goods)):

for v in xrange(max_v,goods[i][0]-1,-1):

f[v] = max(f[v],f[v-goods[i][0]]+goods[i][1])

return f

goods = [[5,12],[4,3],[7,10],[2,3],[6,6]]

test = solution()

print test.zero_one(goods,15)

過程中f更新五輪,結果如下

[0, 0, 0, 0, 0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12]

[0, 0, 0, 0, 3, 12, 12, 12, 12, 15, 15, 15, 15, 15, 15, 15]

[0, 0, 0, 0, 3, 12, 12, 12, 12, 15, 15, 15, 22, 22, 22, 22]

[0, 0, 3, 3, 3, 12, 12, 15, 15, 15, 15, 18, 22, 22, 25, 25]

[0, 0, 3, 3, 3, 12, 12, 15, 15, 15, 15, 18, 22, 22, 25, 25]

01 時間複雜度 空間複雜度

1 時間頻度 乙個演算法中的語句執行次數稱為語句頻度或時間頻度。記為t n n稱為問題的規模,當n不斷變化時,時間頻度t n 也會不斷變化。2 時間複雜度 若有某個輔助函式f n 使得當n趨近於無窮大時,t n f n 的極限值為不等於零的常數,則稱f n 是t n 的同數量級函式。記作t n f ...

01揹包回溯法複雜度 回溯法 求解0 1揹包問題

以前研究過乙個簡單的n皇后問題,對回溯法也有了個模糊的認識,大致理解就是 先一直做某件事,當完成某個條件時或者是觸犯某個條件時,再返回到最近的乙個類似還原點的地方。在用回溯法求解0 1揹包問題的時候,主要遇到三個相對難解決的問題 1,什麼是界限函式 2,什麼時候用它 3,回溯到哪兒。什麼是界限函式?...

01 複雜度分析(上) 時間 空間複雜度講解

我們都知道,資料結構和演算法本身解決的是 快 和 省 的問題,即如何讓 執行得更快,如何讓 更省儲存空間。所以,執行效率是演算法乙個非常重要的考量指標。那如何來衡量你編寫的演算法 的執行效率呢?這裡就要用到時間 空間複雜度分析。1 什麼是複雜度分析?複雜度也叫漸進複雜度,包括時間複雜度和空間複雜度,...