之前學習的幾個揹包都是背幾個一維陣列的板子,沒有深入的理解其中的含義,當碰到乙個相似的揹包的問題時,板子出現了短板,這時就難於寫出題目;
先說 01 揹包:
dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
這裡的 i 表示第幾個物品,j表示目前用的揹包體積;
還有乙個要注意的是揹包不只是求max,min照樣可以,只是初始化問題,我前面的一篇部落格有講到;
偽**:
再談完全揹包:memset
(dp,0,
sizeof(0
));//一般無特殊情況,初始為0
for(
int i=
1;i<=n;i++
)}
學習部落格
完全揹包和01揹包的區別在於乙個物品可以取無數個,直到揹包裝不下;
我們可以很顯然的從 01 揹包推出表示式:
dp[i][j]=max(dp[i][j],dp[i-1][j-v[i]*k]+w[i]*k) (0<=k * v[i]<=j)
偽**:
雖然時間和空間複雜度都很大,但是對於我們深刻理解揹包,理解動態規劃都有很大的意義;memset
(dp,0,
sizeof(0
));//一般無特殊情況,初始為0
for(
int i=
1;i<=n;i++)}
}
多重揹包
這個跟01揹包的區別就是物品的個數有限,它的解法和完全揹包非常相似,物品數量由在揹包容量允許的情況下最多能拿幾個變成了物品有幾個而已;
這裡給出的偽**用一維表示:
這種多重揹包解法的複雜度為o(n^3),一般的題目是過不了的;for
(int i=
1;i<=n;i++)}
}
一種優化方法,就是把每個物品的數量用二進位制拆分,這個方法十分巧妙,拆完之後相當於多個物品當做乙個物品;
**:
分組揹包#include
#define ll long long
#define pa pair
#define lson k<<1
#define rson k<<1|1
#define inf 0x3f3f3f3f
//ios::sync_with_stdio(false);
using
namespace std;
const
int n=
200100
;const
int m=
4001000
;const ll mod=
998244353
;int v,w,s;
int dp[
2100];
struct node
;vectorgoods;
//物品
intmain()
);}if
(s>
0) goods.
push_back()
;}for(
int i=
0;isize()
;i++)}
cout<
}
分組揹包和多重揹包的區別在於,多重揹包列舉第 i 種物品選幾個,分組揹包列舉第 i 組物品選哪個?
模板題:
有 n 組物品和乙個容量是 v 的揹包。
每組物品有若干個,同一組內的物品最多只能選乙個。
每件物品的體積是 vij,價值是 wij,其中 i 是組號,j 是組內編號。
求解將哪些物品裝入揹包,可使物品總體積不超過揹包容量,且總價值最大。
**:
#include
#define ll long long
#define pa pair
#define lson k<<1
#define rson k<<1|1
#define inf 0x3f3f3f3f
//ios::sync_with_stdio(false);
using
namespace std;
const
int n=
200100
;const
int m=
4001000
;const ll mod=
998244353
;int v[
110]
,w[110
],dp[
110]
;int
main()
}}cout<
}
再學01揹包(二)
我認為01揹包就是 對n個物品進行取捨,在一定的限制條件下如何取得最優解的一類問題。此題和再學01揹包 一 中的標準01揹包的比較。標準01揹包和本題的比較 標準01揹包 本題花費 或者代價 cost i cost i 價值 或者貢獻 val i cost i 限制條件 if cost i v 可放...
揹包 學習筆記
前言 揹包學了無數遍,這次總算能記住點東西了qaq 揹包是線性dp中一類重要而特殊的模型。0 1揹包 給定 n 個物品,其中第 i 個物品的體積為 w 價值為 c 現在給你乙個體積為 m 的揹包,問怎樣選擇使得物品總價值最大?我們先考慮樸素演算法。設 f i j 為已經考慮了前 i 個物品,選出總體...
再學動態規劃之 01揹包
寫了之後,發現這題跟01揹包還有點區別。但是寫看這個吧。暴力搜尋的方法。就是每個取或者不去。class solution object defgets self,arr,index,target if target 0 return true elif target 0 return false e...