超大揹包問題解題報告

2021-09-25 11:44:57 字數 1264 閱讀 1286

超大揹包問題:

有重量和價值分別為wi和vi的n個物品,從這些物品中挑選總重量不超過w的物品,

求所有挑選方案中價值總和最大值

限制條件:

1 <= n <= 40

1 <= wi, vi <= 10^15

1 <= w <= 10^15

分析:由於本題w巨大,因此是一道假動態規劃題,如果用動態規劃要麼爆空間要麼超時,於是我們可以抓住n極小的特點,如果將n二分為n/2那麼將會產生複雜度為2^20一秒可過我們於是可以用折半二分。

補充一下本題需要用到的upper_bound和lower_bound。

lower_bound(begin,end,num)

二分查詢陣列中的begin位置到end-1位置二查詢第乙個大於或等於num的數字,找到返回該數字的位址,不存在則返回end。通過返回的位址減去起始位址begin,得到找到數字在陣列中的下標。

upper_bound(begin,end,num)

二分查詢陣列中陣列的begin位置到end-1位置第乙個大於num的數字,找到返回該數字的位址,不存在則返回end。通過返回的位址減去起始位址begin,得到找到數字在陣列中的下標。在從大到小的排序陣列中,過載lower_bound()和upper_bound()

lower_bound(begin,end,greater())

二分查詢陣列中陣列的begin位置到end-1位置第乙個小於或等於num的數字,找到返回該數字的位址,不存在則返回end。通過返回的位址減去起始位址begin,得到找到數字在陣列中的下標。

upper_bound(begin,end,greater())

二分查詢陣列中的begin位置到end-1位置第乙個小於num的數字,找到返回該數字的位址,不存在則返回end。通過返回的位址減去起始位址begin,得到找到數字在陣列中的下標。

附上**

#includeusing namespace std;

const int maxn=40;

long long maxm=1<<20;

typedef long long ll;pairps[1<<(maxn)/2];

int main()

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

} int m=1;///去除多餘的元素: sw[i] <= sw[j] 並且 sv[i] >= sv[j] 則刪除j。

sort(ps,ps+(1<>j&1)

if(sw<=w)

} } cout<}

超大揹包問題題解

有 n nn 個重量和價值分別為 w iw i wi 和 v iv i vi 的物品。從這些物品中挑選出總重量不超過 w ww 的物品放入揹包中,求揹包裡物品價值總和的最大值。n wv 1w1v 2w2.vnw nn space w v 1 space w 1 v 2 space w 2 v n s...

揹包問題解題思路

這個問題解決起來也不是很難,在這裡,我們設定一組資料供以測試,int v 初始化物品價值陣列 int w 初始化物品重量陣列 先嘗試盡量裝又小又值錢的東西,再嘗試第二的 由此反覆,裝不下時,在實行動態轉移方程 for int i 1 i n i else 至此,大框架算是完成了,接下來顯出完整 in...

超大揹包問題

運用二進位制,折半搜尋,其實我覺得本質就是狀壓思想,列舉前一半所有情況並儲存。然後排序保障總質量越大,價值越大。這裡相當於貪心。可以證明的,如果在一堆一一對應的數裡面,只取乙個,另外乙個數越大才越有可能是最優解。這個思想大概只能用在只取乙個上面。再列舉後半部分。算出每一種列舉方式的總質量,w wi就...