題意:有n個物品,揹包總容量為v,第 i 個物品的體積為v
iv_i
vi,價值為w
iw_i
wi,求裝入揹包的最大價值
思路:
狀態表示f[i][j]= 集合:所有只考慮前i種物品且總體積不超過j的方案的集合\\ 屬性:取其中價值最大的方案 \end}\\ 狀態計算:找最後乙個不同點,對第 i 個物品取或者不取 \end
⎩⎪⎨⎪⎧
狀態表示
f[i]
[j]=
printf
("%d\n"
,dp[n]
[m])
;return0;
}空間優化
#include
#include
using namespace std;
const
int maxn=
1010
;int n,m,w[maxn]
,v[maxn]
,f[maxn]
;int
main()
思路:
狀態表示f[i][j]= 集合:所有只考慮前i種物品且總體積不超過j的方案的集合\\ 屬性:取其中價值最大的方案 \end}\\ 狀態計算:找最後乙個不同點,對第 i 個物品取0個,1個,2個 \end
⎩⎪⎨⎪⎧
狀態表示
f[i]
[j]=
} cout<[m]<<
"\n"
;return0;
}優化空間
#include .h>
using namespace std;
const
int maxn=
1010
;int n,m,w[maxn]
,v[maxn]
,f[maxn]
;int
main()
思路:
狀態表示f[i][j]= 集合:所有只考慮前i種物品且總體積不超過j的方案的集合\\ 屬性:取其中價值最大的方案 \end}\\ 狀態計算:找最後乙個不同點,對第 i 個物品有 [0,s]種取法 \end
⎩⎪⎨⎪⎧
狀態表示
f[i]
[j]=
思路:狀態設定:f[i
][j]
f[i][j]
f[i][j
]表示所有前i個物品總體積不超過 j 的方案的集合,然後取乙個價值最大的方案
採用了二進位制優化,因為有 s
ss 件物品,用二進位制可以表示 s
ss 中的任意乙個數
#include .h>
using namespace std;
int n,m,w,v,s;
int f[
2010];
vectorint,
int>
> vec;
intmain()
);}if
(s>0)
vec.
push_back()
;}for(auto i : vec)
for(
int j=m;j>=i.first;
--j)
f[j]
=max
(f[j]
,f[j-i.first]
+i.second)
;printf
("%d\n"
,f[m]);
return0;
}
題意:有n類物品,揹包總容量為v,第i類物品,有s
is_i
si件體積為v
iv_i
vi,價值為w
iw_i
wi,求裝入揹包的最大價值
思路:狀態設定還是f[i
][j]
f[i][j]
f[i][j
]表示前i個物品總體積不超過 j 的最大價值
分析:這裡n範圍在1000,v的範圍在20000,s的範圍在20000以內。如果還是採用二進位制優化的話。時間複雜度是:1000×l
og2(
20000)×
20000
1000\times log_2(20000)\times 20000
1000×l
og2
(200
00)×
2000
0,大約是3e8,會超時。所以可以採用單調佇列優化的方法
優化思路:我們發現每乙個f[i
][j]
f[i][j]
f[i][j
]其實都是從f[i
−1][
j−w]
、f[i
−1][
j−2∗
w]、…
、f[i
−1][
j−s∗
w]
f[i-1][j-w]、f[i-1][j-2*w]、\dots、f[i-1][j-s*w]
f[i−1]
[j−w
]、f[
i−1]
[j−2
∗w]、
…、f[
i−1]
[j−s
∗w]轉移過來的,因此我們可以根據餘數 r 分組,每一組是:r、r
+w、r
+2w、
…r、r+w、r+2w、\dots
r、r+w、
r+2w
、…,維護乙個最大值單調佇列,每次先判斷入隊,然後縮減區間,最後更新 f[j
]f[j]
f[j]
#include .h>
#define ll long
long
using namespace std;
const
int maxn=
2e4+
5,maxm=
1e5+5;
const
int mod=
1e9+
7,inf=
0x7f7f7f7f
;int n,m;
int w[maxn]
,v[maxn]
,s[maxn]
;int q[maxn]
,h,t;
int f[maxn]
,g[maxn]
;int
main()
}}printf
("%d\n"
,f[m]);
return0;
}
揹包問題 01揹包總結
寫這篇部落格的原因是因為自己初學揹包的時候覺得好玄學。只是知道怎麼寫,但是具體是為什麼覺得很玄妙。在此其實希望和我一樣的小白萌新早點明白其中的原理,其實原理很簡單,只要懂了這個圖,我想01揹包就不成問題了。首先要明確這張表是至底向上,從左到右生成的。關於01揹包的題目暫時整理了一點。1.簡單01揹包...
揹包問題總結
標籤 acm dp 揹包 n 物品,乙個揹包,每個物品價值wi 體積vi 揹包容量 c 求最大價值 對於物品 i可選可不選 fi j fi 1 j vi j 0 fi j max c j vi 給定 n 種物品和乙個揹包。第 i種物品的價值是 wi 其體積為vi 揹包的容量為 c 同一種物品的數量無...
揹包問題總結
揹包問題主要是分為三種 0 1揹包,完全揹包,多重揹包 1 0 1揹包 定義 何謂0 1揹包,可以這樣想,那裡有一堆值錢的東西,每一樣東西只有一件,他們的價值和體積都不一樣,現在要你從這n件裡面挑選一些放到乙個容量一定的揹包裡面,使得你的揹包裡的東西總價值最大。對於這些東西的每一件,你可以選擇放進你...