大揹包問題(01揹包)

2021-09-07 00:17:59 字數 1294 閱讀 7894

大揹包問題:有n乙個重量和**值分別w[i]和v[i]專案。出的這些產品中的總重量不超過w專案。查詢所有選定的方案**值的最大總和值。

其中,1 ≤ n ≤ 40, 1 ≤ w[i], v[i] ≤ 10^15, 1 ≤ w ≤ 10^15.

這個問題給人的第一感覺就是普通的01揹包。

只是,看完資料範圍會發現。這次價值和重量都能夠是很大的數值,相比之下n比較小。使用dp求解揹包為題的複雜度是o(nw),因此不能用來解決問題。此時我們應該利用n比較小的特點來尋找其它方法。

挑選物品的方案總共同擁有2^n種,所以不能直接列舉,可是假設將物品分成兩半再列舉的話。因為每部分最多僅僅有20個。這是可行的。我們把前半部分中的挑選方法相應的重量和價值總和記為w1、v1,這樣在後半部分尋找總重w2 ≤ w - w1時使v2最大的選取方法就可以。

因此,我們要思考從列舉得到的(w2,v2)集合中高效尋找max的方法。首先,顯然我們能夠排除全部w2[i] ≤ w2[j] 而且 v2[i] >= v2[j]的j。

這一點能夠依照w2、v2的字典序排序後做到。

此後剩餘的元素都滿足w2[i] < w2[j] <=> v2[i] < v2[j]。要計算max的話,僅僅要尋找滿足w2[i] <= w'的最大的i就能夠了。這能夠用二分搜尋完畢。剩餘的元素個數為m的話,一次搜尋須要o(logm)的時間。由於m≤2^(n/2),所以這個演算法總的時間複雜度是o(n * 2^(n/2)),能夠在實現內解決這個問題。

#include #include #include using namespace std;

const int n = 50;

const long long inf = 0x3fffffff;

typedef long long ll;

int n;

ll w[n], v[n];

ll w;

pair pi[1 << (n / 2)];

void solve()

}pi[i] = make_pair(sw, sv);

}sort(pi, pi + (1 << n2));

int m = 1;

for(int i = 1; i < (1 << n2); i++)

}ll res = 0;

for(int i = 0; i < (1 << (n - n2)); i++)

}if(sw <= w)

}printf("%lld\n", res);

}int main()

solve();

}return 0;

}

01揹包問題 大揹包

i i 物體索引 0 n j jj 揹包容量 0 w dpdp dp 最大價值 為了降低時間複雜度我們必須要改變dp陣列含義為。由於時間複雜度主要由i ii和j jj的含義決定,所以我們必須將i ii和j jj的含義於取值返回比較小的n nn和v vv陣列聯絡起來,將較大的w ww與dpdp dp陣...

揹包問題 01揹包

有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。01揹包中的 01 就是一種物品只有1件,你可以選擇放進去揹包即1,也可以選擇不放入揹包中即0。include include using namespace std const int ...

揹包問題(01揹包)

1085 揹包問題 在n件物品取出若干件放在容量為w的揹包裡,每件物品的體積為w1,w2 wn wi為整數 與之相對應的價值為p1,p2 pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物品的數量,w為揹包的容量。1 n 100,1 w 10000...