DP背包(一)
01背包
for(int i=0;i<n;i++) //遍歷每一件物品for(int j=v;j>=wei[i];j--)//遍歷背包容量,表示在上一層的基礎(chǔ)上,容量為J時(shí),第i件物品裝或不裝的最優(yōu)解;dp[j]=max(dp[j-wei[i]]+val[i],dp[j]);初始化細(xì)節(jié):裝滿dp[0]=0;其余賦值-INF;不裝滿全初始化為0;
完全背包
for(int i=0;i<n;i++) //遍歷每一類物品for(int j=wei[i];j<=v;j++)//遍歷容量,此時(shí)代表第一類物品選了幾件。與0/1區(qū)別正序遍歷dp[j]=max(dp[j-wei[i]]+val[i],dp[j]);多重背包
for(int i=0;i<n;i++) //遍歷每一個(gè)物品 for(int j=0;j<=num[i];j++) //遍歷物品的數(shù)量 for(int k=m;k>=weight[i];k--) //當(dāng)做01背包來處理 { //取01背包情況的dp[k]和dp[k-weight[i]]+value[i]的最大值 dp[k]=max( dp[k],dp[k-weight[i]]+value[i] );}二進(jìn)制優(yōu)化
優(yōu)化原因:
多重背包轉(zhuǎn)換成 01 背包問題就是多了個(gè)初始化,把它的件數(shù)C 用
分解成若干個(gè)件數(shù)的集合,這里面數(shù)字可以組合成任意小于等于C
的件數(shù),而且不會(huì)重復(fù),之所以叫二進(jìn)制分解,是因?yàn)檫@樣分解可
以用數(shù)字的二進(jìn)制形式來解釋
比如:7的二進(jìn)制 7 = 111 它可以分解成 001 010 100 這三個(gè)數(shù)可以
組合成任意小于等于7 的數(shù),而且每種組合都會(huì)得到不同的數(shù)
15 = 1111 可分解成 0001 0010 0100 1000 四個(gè)數(shù)字
如果13 = 1101 則分解為 0001 0010 0100 0110 前三個(gè)數(shù)字可以組合成
7以內(nèi)任意一個(gè)數(shù),加上 0110 = 6 可以組合成任意一個(gè)大于6 小于13
的數(shù),雖然有重復(fù)但總是能把 13 以內(nèi)所有的數(shù)都考慮到了,基于這種
思想去把多件物品轉(zhuǎn)換為,多種一件物品,就可用01 背包求解了。
好像單調(diào)隊(duì)列也能優(yōu)化,多重背包;
下一期整理
總結(jié)
- 上一篇: CPU测试_性能测试cpu温度多少范围正
- 下一篇: ACM-ICPC 2019 山东省省赛