多重揹包暴力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種大公尺,每種大公尺都是袋裝產品,其 不等,並且只能整袋購買。請問 你用有限的資金最多能採購多少公斤糧食呢?後記 人生是乙個充滿了變數的生命過程,天災 人禍 病痛是我們生...