各種揹包的總結

2022-05-02 01:54:20 字數 2902 閱讀 4887

現在才開始寫這種彩筆東西qaq

這個不想多講了

int n, v, w, v, dp[maxn];

int main()

printf("%d\n", dp[v]);

return 0;

}

這個也沒什麼好講的

就是把迴圈順序換一下

int n, v, w, v, dp[maxn];

int main()

printf("%d\n", dp[v]);

return 0;

}

指拆分成乙個個,跑01揹包

**就算了

如標題一樣,拆完跑01揹包,沒什麼好說的

int wei[maxn << 2], val[maxn << 2], dp[maxn], cnt;

int main()

for (int j = 1; c >= j; j <<= 1)

if (c)

}for (int i = 1; i <= cnt; ++i)

for (int j = m; j >= wei[i]; --j)

dp[j] = max(dp[j], dp[j - wei[i]] + val[i]);

printf("%d", dp[m]);

return 0;

}

首先我們有普通的轉移方程

設\(vol\)為體積,\(wei\)為價值,\(num\)為數量

令\(lim=\min(\left \lfloor \frac \right \rfloor,num)\)

\[dp[i][j]=\max_

\]然後我們可以通過對餘數進行分組,每組之間互不影響,來用上單調佇列求出這個最大值

設我們選了\(k\)個這個物品(\(k\le a=\frac\)),此時餘數為\(b=j\%vol\)

轉移方程變為了

\[dp[i][j]=\max_(dp[i-1][(a-k)*vol+b]+k*wei)

\]令\(k'=a-k\)

\[dp[i][j]=\max_(dp[i-1][k'*vol+b]-k'*wei)+a*wei

\]然後我們就可以上單調佇列了

這是模板多重揹包的code(順便說下,前面那幾個的模板這個**上也有)

#includeusing namespace std;

inline void read(int& x)

#define maxn 100005

int dp[maxn], n, v, vol, wei, num, ans, q[maxn], l, r, pos[maxn];

int main()

} }int ans = 0;

for (int i = 1; i <= v; ++i) ans = max(ans, dp[i]);

printf("%d\n", ans);

return 0;

}

模 板 三 合 一

#define maxn 10005

int n, v, w[maxn << 3], v[maxn << 3], s[maxn << 3], dp[maxn], tot;

int q[maxn], pos[maxn];

int main()

} printf("%d\n", dp[v]);

return 0;

}

就是兩層01揹包迴圈

#define maxn 1005

int dp[maxn][maxn];

int main()

printf("%d\n",dp[v][m]);

return 0;

}

大概就是組內01,各組01

#define mp make_pair

struct group

g[105];

int f[105];

int main()

for(int i=1;i<=100;++i)

if(g[i].num)

for(int j=v;j;--j)//注意兩個迴圈的順序,這樣保證了同一組最多選乙個

for(vector>::iterator it=g[i].a.begin();it!=g[i].a.end();++it)

if((*it).first<=j)

f[j]=max(f[j],f[j-(*it).first]+(*it).second);

printf("%d\n",f[v]);

return 0;

}

這其實有點像樹形dp了

其實就是樹形dp

結構會形成一顆樹(假設沒有環)

#define maxn 105

struct edge

eg[maxn<<1];

int head[maxn],edgenum,n,v,root,val[maxn],w[maxn];

int dp[maxn][maxn];

inline void add(int fr,int to)

; head[fr]=edgenum;

}void dfs(int rt,int fa)

for(int i=v;i>=w[rt];--i)//必選當前這個點

dp[rt][i]=dp[rt][i-w[rt]]+val[rt];

for(int i=0;idp[rt][i]=0;

}int main()

dfs(root,0);

printf("%d\n",dp[root][v]);

return 0;

}

01揹包,多重揹包,完全揹包 總結

可以先看下這篇部落格理解下動態規劃的思想 初識動態規劃 寫在前面的 這篇部落格主要寫的是,乙個容量為v的揹包去裝n個物品能獲得的最優解的問題 問題簡述 現在有乙個揹包,它能容納的最大重量為v,問揹包所能帶走的最大價值是多少?01揹包 有n個物品,每個物品的重量為w i 每個物品的價值為h i 對於每...

揹包問題總結 01揹包 完全揹包 多重揹包

1 01揹包問題 有n個物品,每個物品只有一件。動歸方程 1 二維陣列解法 dp i j max 2 一維陣列解法 dp j max 附 hdu 2602 bone collector 二維陣列 include include int dp 1005 1005 int main else dp i ...

揹包問題 01揹包總結

寫這篇部落格的原因是因為自己初學揹包的時候覺得好玄學。只是知道怎麼寫,但是具體是為什麼覺得很玄妙。在此其實希望和我一樣的小白萌新早點明白其中的原理,其實原理很簡單,只要懂了這個圖,我想01揹包就不成問題了。首先要明確這張表是至底向上,從左到右生成的。關於01揹包的題目暫時整理了一點。1.簡單01揹包...