n
nn個物品,大小為w
ww的揹包。
每個物品的大小可以表示為wi=
ai2b
iw_i=a_i2^
wi=ai
2bi
,有價值v
iv_i
vi。
求選擇一些物品不超過揹包的大小使得價值最大。
設先計算b
ib_i
bi相同的物品,設fi,
jf_
fi,j
表示只計算b=i
b=ib=
i的物品時,乙個容量為j∗2
ij*2^
j∗2i
時的揹包時的最大價值。
然後將多個揹包合併,設gi,
jg_
gi,j
表示只計算b≤i
b\leq i
b≤i的物品時,容量為j∗2
i+w&
(2i−
1)
j*2^i+w\&(2^i-1)
j∗2i+w
&(2i
−1)時的最大價值。
然後有轉移方程gi,
j=ma
xg_=max\+g_\ \ \}
gi,j=
max然後答案就是g30,
0g_
g30,0
時間複雜度o(n
loga∑
a)
o(n\log a\sum a)
o(nloga∑
a)
#include
#include
#include
#include
using
namespace std;
const
int n=
110;
int n,w,a[n]
,v[n]
,lim[n]
;int f[n]
[n*n]
,g[n]
[n*n]
;vector<
int> q[n]
;int
main()
for(
int i=
0;i<=
30;i++
)for
(int j=
0;j.size()
;j++
)for
(int k=lim[i]
;k>=a[q[i]
[j]]
;k--
) f[i]
[k]=
max(f[i]
[k-a[q[i]
[j]]
]+v[q[i]
[j]]
,f[i]
[k])
;for
(int i=
0;i<=lim[0]
;i++
)g[0
][i]
=f[0
][i]
;for
(int i=
1;i<=
30;i++
)printf
("%d\n"
,g[30][
0]);
}}
P3188 HNOI2007 夢幻島寶珠
傳送門 注意到 a,b 不大 考慮對每乙個 a 2 b 的 b 分別揹包 設 f i j 表示只考慮 b i 的物品時,容量為 j sum a 的最大價值 這個就是普通的 01 揹包 考慮把 f i j 之間合併起來,為了得到容量為 w 時的答案,我們要把 f 的含義稍微變化一下 變成 f i j ...
洛谷 P3188 HNOI2007 夢幻島寶珠
題目描述 給你n顆寶石,每顆寶石都有重量和價值。要你從這些寶石中選取一些寶石,保證總重量不超過w,且總價值最大為 並輸出最大的總價值。資料範圍 n 100 w 2 30 並且保證每顆寶石的重量符合a 2 b a 10 b 30 輸入格式 輸入檔案中包含多組資料。每組資料的格式如下 第一行是兩個正整數...
洛谷 P3188 HNOI2007 夢幻島寶珠
給你n顆寶石,每顆寶石都有重量和價值。要你從這些寶石中選取一些寶石,保證總重量不超過w,且總價值最大為 並輸出最大的總價值。資料範圍 n 100 w 2 30,並且保證每顆寶石的重量符合a 2 b a 10 b 30 輸入檔案中包含多組資料。每組資料的格式如下 第一行是兩個正整數n和w,1 n 10...