動態規劃之01揹包,完全揹包,分組揹包
阿新 • • 發佈:2019-02-01
一:01揹包
每樣物品只能取一件
狀態轉移方程 f[i][v]=max(f[i-1][v],f[i-1][v-weight[i]]+cost[i])
f[i][v]表示前i件物品裝入v的空間裡的最大價值,考慮第i件物品是否放入的問題,一種是不放入那就是前i-1件物品放入v中,另一種考慮放入則是前i-1件物品放入v-weight[i]空間的最大值
將空間縮減成VN
for (int i = 0; i != n; ++i) { for (int v = V; v >= things[i].weight; --v) { f[x] = max(f[x], f[x - things[i].weight] + things[i].price); } }
二:完全揹包
由01揹包聯想,將每個物品能放的最大數量,按照二進位制的形式分成一個一個的小物品,例如5個1物品,能分成4個1物品和1個1物品,然後將4個1物品當成一個放入01揹包中,將1個1物品放入完全揹包中,時間複雜度為超O(VN)
若想時間複雜度不超,則模板
for (int i = 0; i != n; ++i)
{
for (int v = things[i].weight; v <= V; ++v)
{
f[x] = max(f[x], f[x - things[i].weight] + things[i].price);
}
}
三:多重揹包
有N種物品和一個容量為V的揹包。第
void 01bag(int a,int b)//a表示價格,b表示重量 { for (int v = V; v >= b; --b) { f[v] = max(f[v], f[v - b] + a); } } void completebag(int a, int b) //a表示價格,b表示重量 { for (int v = b; v <= V; ++v) { f[v] = max(f[v], f[v - b] + a); } } void multibag(int a, int b, int c)//多重揹包c表示數量 { if (b*c >= V) { completebag(a, b); return; } int k = 1; while (c>=k) { 01bag(a*k, b*k); c = c - k; k *= 2; } 01bag(c*a, b*a); }