HDU2191 多重揹包

2022-03-27 06:32:43 字數 1234 閱讀 9624

多重揹包暴力dp為$o(nv^2)$,n為物品個數,v為揹包容量,

二進位制優化複雜度為$o(nv\log v)$。

1 #include2 #include3

#define rep(i,l,r) for (int i=(l); i<=(r); i++)

4using

namespace

std;56

const

int n=1010;7

intt,n,m,v,w,tot,f[n];89

intmain()

20 printf("

%d\n

",f[m]);21}

22return0;

23 }

二進位制優化

單調佇列優化複雜度為$o(nv)$。

單調佇列的主要思想是從dp方程入手:$$f_=max\+(j-k)\times w\}=max\-k*w\}+j*w$$

v為當前物品的代價,w為價值。j-tot<=k<=j,tot為當前物品的個數。

發現所有轉移都是在同一剩餘系下做的,所以只要對每個剩餘系分別維護乙個單調佇列即可。

1 #include2 #include3

#define rep(i,l,r) for (int i=(l); i<=(r); i++)

4using

namespace

std;56

const

int n=1010;7

intt,n,m,v,w,tot,q1[n],q2[n],f[n];89

void dp(int v,int w,int

tot)+j*w[i](j-tot<=k<=j)

13if (st<=ed && q1[st]//

j-tot<=k<=j

14int t=f[i+j*v]-j*w;//

佇列中存f[i+j*v]-j*w

15 f[i+j*v]=max(f[i+j*v],q2[st]+j*w);//

更新f[i+j*v]

16while (st<=ed && t>=q2[ed]) ed--;//

將j放入佇列

17 q1[++ed]=j; q2[ed]=t;18}

19}20}

2122

intmain()

31return0;

32 }

HDU 2191 多重揹包

problem description 急!災區的食物依然短缺!為了挽救災區同胞的生命,心繫災區同胞的你準備自己採購一些糧食支援災區,現在假設你一共有資金n元,而市場有m種大公尺,每種大公尺都是袋裝產品,其 不等,並且只能整袋購買。請問 你用有限的資金最多能採購多少公斤糧食呢?後記 人生是乙個充滿了...

HDU 2191 多重揹包

題目大意 有m種公尺,給出每種公尺花費,重量和數量,問n元能獲得的最大重量是多少 題目思路 對於每個包,如果數量 花費 n,那麼很明顯直接多重揹包即可,否則就需要用到二進位制拆分法。由於0 2 k 1內所有的數字都可以通過2 0 2 1 2 2.2 k 1 中若干個數字得到。那麼可以把數量為c的物品...

HDU 2191 多重揹包

急!災區的食物依然短缺!為了挽救災區同胞的生命,心繫災區同胞的你準備自己採購一些糧食支援災區,現在假設你一共有資金n元,而市場有m種大公尺,每種大公尺都是袋裝產品,其 不等,並且只能整袋購買。請問 你用有限的資金最多能採購多少公斤糧食呢?後記 人生是乙個充滿了變數的生命過程,天災 人禍 病痛是我們生...