【模板】動態規劃的揹包問題

01揹包:ide

n件物品,揹包最大載重爲W,第i件物品的重量爲w[i],價值爲v[i],求在不超過W的狀況下揹包內物品價值的最大總和。優化

狀態轉移方程:spa

  f[j] = max(f[j], f[j - w[i]] + v[i])code

  1≤i≤n, w[i]≤j≤Wblog

1 for(int i=1; i<=n; ++i) 2 for(int j=W; j>=w[i]; --j) 3     f[j] = max(f[j], f[j - w[i]] + v[i]);
01揹包

 

徹底揹包:class

n種物品,每種物品能夠選無數次,循環

揹包最大載重爲W,第i種物品的重量爲w[i],價值爲v[i],求在不超過W的狀況下揹包內物品價值的最大總和。二進制

DP方程和01揹包的同樣,只不過循環順序要從逆序變成正序im

1 for(int i=1; i<=n; ++i) 2 for(int j=w[i]; j<=W; ++j) 3     f[j] = max(f[j], f[j - w[i]] + v[i]);
徹底揹包

 

多重揹包:img

n種物品,每種物品有p[i]個,

揹包最大載重爲W,第i種物品的重量爲w[i],價值爲v[i],求在不超過W的狀況下揹包內物品價值的最大總和。

DP方程仍是和01揹包同樣,不過要在第二層加一個p[i]次的循環,表示這一件物品要選p[i]

1 for(int i=1; i<=n; ++i) 2      for(int k=1; k<=p[i]; ++k) 3          for(int j=W; j>=w[i]; --j) 4              f[j] = max(f[j], f[j - w[i]] + v[i]);
多重揹包未優化

 

多重揹包的二進制優化:

k拆成1 + 2  + 4 + 8  + ... + 2n + x的形式,這樣原來的k件物品就變成了logk件,再作01揹包就好

 1 int main() {  2     n = read(), W = read();  3     int cnt = 0;  4     for(int i=1; i<=n; ++i) {  5             w[i] = read(), v[i] = read(), p[i] = read();  6             int s = 1;  7             while(p[i] > s) {  8                 ww[++cnt] = w[i] * s;  9                 vv[cnt] = v[i] * s; 10                 p[i] -= s; 11                 s <<= 1; 12  } 13             if(p[i]) { 14                 ww[++cnt] = w[i] * p[i]; 15                 vv[cnt] = v[i] * p[i]; 16  } 17  } 18     for(int i=1; i<=cnt; ++i) 19         for(int j=W; j>=ww[i]; --j) 20             f[j] = max(f[j], f[j - ww[i]] + vv[i]); 21 }
多重揹包二進制優化
相關文章
相關標籤/搜索