《背包九講》筆記

背包問題

題意:給出背包的容量端逼,以及一批物品的價值和大小揖铜,求最大價值。

01背包問題

題意

每個物品只能放入一次困介。

思路

f[i][v]表示,第i個大小為v的物品放入時的總價值蘸际。
c[i]表示第i個物品的價值座哩。w[i]為第i個物品的大小。
狀態(tài)轉(zhuǎn)移方程:f[i][v] = max(f[i-1][v], f[i-1][v-w[i]]+c[i]);
狀態(tài)轉(zhuǎn)移方程表示粮彤,取放入或者不放入第i個物品兩種情況的最大值根穷。

空間優(yōu)化(滾動數(shù)組)

初始狀態(tài)方程的空間復雜度是O(V*W),可以進一步優(yōu)化导坟。
可以將空間優(yōu)化為O(2*W)屿良,即縱向大小為2。

for(i=1; i<=N; i++){
  for(j=t[i]; j<=V; j++)
    f[t^1][j] = max(f[c][j-w[i]]+c[i], f[t][j]);
  t ^= 1;
}

異或滾動可以在0和1之間切換惫周,可以利用上下反復更新尘惧。

空間優(yōu)化(一維數(shù)組)

既然可以用兩行進行更新,那為什么不能用一行递递。
觀察問題喷橙,兩行更新時,用上一行的前部分更新下一行的后部分登舞。
所以單行更新時要從后往前遍歷贰逾,這樣可以用前面的更新后面的。

for(i=1; i<=N; i++)
  for(j=V; j>=w[i]; j--)
    f[j] = max(f[j-w[i]]+c[i], f[j]);

這樣就可以用一維數(shù)組來進行更新菠秒。
可以寫成函數(shù)疙剑,封裝起來。

void ZeroOnePack(int cost, int weight){
    for(int i=V; i>=weight; i++)
        f[i] = max(f[i], f[i-weight]+cost)
}

初始化的細節(jié)問題

一般問題會有兩種問法:

  1. 剛好裝滿背包
  2. 不用裝滿背包
    如果是第一種,f[0]=0,f[1]……f[N]=INF;
    如果是第二種核芽,f[0]……f[N]=INF;
    理解:
    如果是第一種囚戚,初始狀態(tài)只有0符合理想狀態(tài),只有0才能被空“裝滿”轧简。
    如果是第二種驰坊,所有都符合理想狀態(tài)。

完全背包問題

題意

和01背包相似哮独,所不同的是可取的物品數(shù)是無限拳芙。

前置小優(yōu)化

對于i``j兩個物品,如果c[i]>c[j] && w[i]<w[j]皮璧,就舍去i物品舟扎。
另外,針對背包問題而言悴务,比較不錯的一種方法是:首先將重量大于V的物品去掉睹限,然后使用類似計數(shù)排序的做法,計算出費用相同的物品中價值最高的是哪個讯檐,可以O(V+N)地完成這個優(yōu)化羡疗。

基本思路

狀態(tài)轉(zhuǎn)移方程f[i][v]=max{f[i-1][v-k*w[i]]+k*c[i]},(0<=k*w[i]<=V)

轉(zhuǎn)化為01背包求解

一件物品最多只能放V/c[i]件,所以可以把一件物品别洪,看成V/c[i]件物品叨恨,作為01背包解答。
另一種更好的辦法是把第i種物品拆成大小為w[i]*2^k挖垛、價值為c[i]*2^k的若干件物品痒钝,其中k滿足w[i]*2^k<=V。這是二進制的思想痢毒,因為不管最優(yōu)策略選幾件第i種物品送矩,總可以表示成若干個2^k件物品的和。這樣把每種物品拆成O(log(V/w[i]))件物品闸准,是一個很大的改進益愈。

O(VN)算法

for(int i=1; i<=N; i++)
    for(int j=w[i]; j<=V; j++)
        f[j] = max{f[v], f[v-w[i]]+c[i]};

這個算法和之前的01背包相比只是第二層的遍歷方向改變了。因為01背包要保證每個物品只能選擇一次夷家,但是完全背包不必蒸其,所以改變遍歷方向就可以得到結(jié)果。
這個算法也可以從另外的思路中得出库快,例如摸袁,基本思路中的公式可以化作這個形式:f[i][v]=max(f[i-1][v], f[i][v-w[i]]+c[i]);
用函數(shù)封裝:

void CompletePack(int cost, int weight){
    for(int i=weight; i<=V; i++)
        f[i] = max(f[i], f[i-weight]+cost);
}

多重背包問題

題意

每件物品數(shù)量不一定為1但有限。

基本思路

問題和完全背包很相似义屏。
f[i][v]=max{f[i-1][v-k*c[i]]+k*w[I]}(0<=k<=n[I])
復雜度為O(V*Σn[i])靠汁。

轉(zhuǎn)化為01背包問題

n[i]存儲蜂大,可以將每種物品轉(zhuǎn)化為n[i]件物品,然后用01背包方案求解蝶怔。復雜度不變奶浦。
如果要進行優(yōu)化的話,依然用二進制思想踢星,同上澳叉。
這樣可以將時間優(yōu)化為O(V*Σlog n[i])

void MultiplePack(int weight, int cost, int amount){
    if(cost * amount >= V){
        CompletePack(cost, weight);
        return;
    }
    int k = 1;
    while(k < num){// num 為物品種數(shù)
        ZeroOnePack(k*cost, k*weight);
        amount = amount-k;
        k *= 2;
    }
    ZeroOnePack(amount*cost, amount*weight);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末沐悦,一起剝皮案震驚了整個濱河市成洗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌藏否,老刑警劉巖瓶殃,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異副签,居然都是意外死亡遥椿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門淆储,熙熙樓的掌柜王于貴愁眉苦臉地迎上來修壕,“玉大人,你說我怎么就攤上這事遏考。” “怎么了蓝谨?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵灌具,是天一觀的道長。 經(jīng)常有香客問我譬巫,道長咖楣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任芦昔,我火速辦了婚禮诱贿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘咕缎。我一直安慰自己珠十,他們只是感情好,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布凭豪。 她就那樣靜靜地躺著焙蹭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嫂伞。 梳的紋絲不亂的頭發(fā)上孔厉,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天拯钻,我揣著相機與錄音,去河邊找鬼撰豺。 笑死粪般,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的污桦。 我是一名探鬼主播亩歹,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼寡润!你這毒婦竟也來了捆憎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤梭纹,失蹤者是張志新(化名)和其女友劉穎躲惰,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體变抽,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡础拨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了绍载。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诡宗。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖击儡,靈堂內(nèi)的尸體忽然破棺而出塔沃,到底是詐尸還是另有隱情,我是刑警寧澤阳谍,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布蛀柴,位于F島的核電站,受9級特大地震影響矫夯,放射性物質(zhì)發(fā)生泄漏鸽疾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一训貌、第九天 我趴在偏房一處隱蔽的房頂上張望制肮。 院中可真熱鬧,春花似錦递沪、人聲如沸豺鼻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拘领。三九已至,卻和暖如春樱调,著一層夾襖步出監(jiān)牢的瞬間约素,已是汗流浹背届良。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留圣猎,地道東北人士葫。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像送悔,于是被迫代替她去往敵國和親慢显。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容