超大揹包問題:
有重量和價值分別為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就...