DP 揹包問題(一)

2022-07-27 05:15:12 字數 2591 閱讀 5792

以前不是很重視 dp ,遇到 dp 就寫貪心、暴搜……其實這是非常錯誤的,現在開始練習 dp 了才發現,我好菜……

對於dp的整理,先從眾所周知的揹包問題開始。

———————— 01揹包:n 個物品,重量和價值分別為 w[i]、v[i],揹包容量 w,求所有挑選方案中價值總和的最大值。

dp 方程 :dp[j] = max ( dp[j] , dp[ j - w[i] ] + v[i] ) ,其中 dp[j]為使用 j 的容量獲得的最大價值,i 為第 i 件物品。

**:

1 #include2 #include3 #include4 #include5 #include6 #include

7using

namespace

std;

8int n,w,w[2000],v[2000],dp[2000];9

intmain()

16 printf("%d"

,dp[w]);

17return0;

18 }

01揹包

———————— 完全揹包:n 種物品,數目不限,其他的和 01揹包 一 樣。

dp 方程 : dp[j] = max ( dp[j] , dp[ j - w[i] + v[i] ) ,是不是感覺和 01揹包 一樣?其實,就是 一樣……-- ^ --|||||,但**有細微差別……

**:

1 #include2 #include3 #include4 #include5 #include6 #include

7using

namespace

std;

8int n,w,w[2000],v[2000],dp[2000];9

intmain()

16 printf("%d"

,dp[w]);

17return0;

18 }

完全揹包

那麼,問題來了,為什麼 01揹包 是倒著

迴圈,而 完全揹包 是正著迴圈……動筆模擬一下,你會發現且理解 — 正著迴圈會對一件物品重複選取╮(╯_╰)╭,而倒著迴圈就不會……

———————— 多重揹包:n 種物品,給定數目 m[i],其他和 01 揹包一樣。

dp 方程:dp[j] =max ( dp[j],dp[ j - w[i] ] + v[i] ),&%&……¥怎麼又一樣,其實 多重揹包 就是特殊處理化的 01揹包,這個特殊處理就是 二進位制拆分。

二進位制拆分:眾所周知什麼是二進位制,二進位制拆分就是把 m[i] 個物品拆成 1個物品、2個物品組成的新物品、4個物品組成的新物品、8個物品組成的新物品……一                              直到不能拆為止,因為二進位制可以 表示 出任何實數的嘛。

**:

1 #include2 #include3 #include4 #include5 #include6 #include

7using

namespace

std;

8int n,w,w[2000],v[2000],dp[2000],m[2000];9

intmain()

23 w[i]=m[i]*w[i];

24 v[i]=m[i]*v[i];25}

26for(int i=1;i<=n;i++)

27for(int j=w;j>=w[i];j--)

30 printf("%d"

,dp[w]);

31return0;

32 }

多重揹包

———————— 三種混合揹包(01揹包、完全揹包、多重揹包):這種問題就是給定 m[i],若 m[i] 為 -1,則為數目無限,否則數目有限,其他的和 01揹包 一樣。雖然寫著是三種                              混合揹包,但我認為實際上是兩種揹包,多重揹包 和 完全揹包。方法就是能拆分的就拆分,在迴圈的時候,判斷一下,如果是 完全揹包 就正著迴圈,不然就倒                                著迴圈…………蠻easy的qaq~

**:

1 #include2 #include3 #include4 #include5 #include6 #include

7using

namespace

std;

8int n,w,w[2000],v[2000],dp[2000],m[2000];9

intmain()

23 w[i]=m[i]*w[i];

24 v[i]=m[i]*v[i];25}

26for(int i=1;i<=n;i++)

27if(m[i]!=-1)28

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

31else

32for(int j=w[i];j<=w;j++)

33 dp[j]=max(dp[j],dp[j-w[i]]+v[i]);

34 printf("%d"

,dp[w]);

35return0;

36 }

混合揹包

DP 揹包問題

大牛 以下使用滾到陣列 若輸入要求一般,可以邊定義狀態邊輸入,不需儲存 memset f,0,sizeof int n 若求最小值,除 f 0 其餘初始化為 inf,f 0 0是必須的 求最大最小都一樣 確保有從無到有的起點 0 1揹包 一般形式 f i v max f i 1 v f i 1 v ...

揹包問題 DP

01揹包 現在有1個體積為mmax的揹包和n種物品 每種物品只有1個 每種物品的體積和價值分別是v i 和w i 求這個揹包最多可以裝價值多少的物品。這是最基礎的揹包問題,特點是 每種物品僅有一件,可以選擇放或不放。用子問題定義狀態 設f i j 表示前i件物品恰放入乙個容量為j的揹包可以獲得的最大...

DP 揹包問題

小明同學在參加一場考試,考試時間2個小時。試卷上一共有n道題目,小明要在規定時間內,完成一定數量的題目。考試中不限制試題作答順序,對於 i 第道題目,小明有三種不同的策略可以選擇 1 直接跳過這道題目,不花費時間,本題得0分。2 只做一部分題目,花費pi分鐘的時間,本題可以得到ai分。3 做完整個題...