01揹包的特點:
物品只有一件,可以選擇放或者不放。
問題:
有n件物品和乙個容量為v的揹包。放入第i
ii件物品耗費的費用是c
ic_i
ci,得到的價值是w
iw_i
wi。求解將哪些物品裝入揹包可以使物品的價值總和最大。
思路:
把整個問題,拆分成幾個子問題。則面對第i
ii個物品時,只需要考慮放或者不放。
所以不妨定義乙個狀態:即f[i
,v]f[i,v]
f[i,v]
表示前i
ii件物品放入容量為v
vv的揹包獲得的最大價值。
所以可以得到狀態方程:
f [i
,v]=
maxf[i,v]=max\
f[i,v]
=max
下面解釋這個狀態方程。
初始狀態如下圖(不要問為什麼字寫這麼醜):
第一行全部初始化為0,表示將前0件物品裝入揹包(即沒有裝入物品)時的最大價值為0。
面對第i
ii個物品,只需要考慮裝或不裝兩種情況。
若不裝,則:
f [i
,v]=
f[i−
1,v]
f[i,v]=f[i-1,v]
f[i,v]
=f[i
−1,v
]若裝,則:
f [i
,v]=
f[i−
1,v−
ci]+
wif[i,v]=f[i-1,v-c_i]+w_i
f[i,v]
=f[i
−1,v
−ci
]+wi
前提是揹包裝的下第i
ii個物品,即v≥c
iv≥c_i
v≥ci
所以只需要考慮兩個中的最大值即可。
其實這個思路有點像之前學過的貪心演算法
但是不同的是:
貪心保證求到的是區域性最優解
但是揹包問題中,當前狀態下的區域性最優解組成的解並不一定是全域性最優解,當前的區域性最優解受之前的選擇的影響
所以,這個過程其實有點像之前學過的記憶化搜尋,即儲存每一步的狀態,之後用到這一步時只需要進行讀取操作,不需要重複計算。(有點像求最短路)
多說無益,上一道題。
hdu2602
經典的01揹包問題,套板子可以直接過。
題解**:
#include
#include
#include
using
namespace std;
intmain()
for(
int i=
1; i<=a; i++
)for
(int i=
1; i<=a; i++)}
cout<
[b]<
n--; 輸出dp[a]
[b];
} 我總認為揹包不一定會恰好裝滿。
return0;
}
完全揹包的特點:物品有無窮件,要考慮的不是第i
ii件物品拿不拿而是拿幾件
題目:有n種物品和乙個容量為v的揹包。每種物品有無限件,放入第i
ii種物品耗費的費用是c
ic_i
ci,得到的價值是w
iw_i
wi。求解將哪些物品裝入揹包可以使物品的價值總和最大。
與01揹包不同的是,每種物品可以裝的個數是
0~v /c
i(向下
取整)v/c_i(向下取整)
v/ci(
向下取整
)所以類似的,可以得到狀態方程:
f [i
,v]=
max∣
(0≤k
ci≤v
)f[i,v]=max\|(0≤kc_i≤v)
f[i,v]
=max
∣(0≤
kci
≤v)也就轉化成了01揹包
不說廢話,上題:
hdu2159
題意:耐久度為揹包體積,要殺的怪為物品種類,得到的經驗為最後的總價值,殺的小怪數為拿的物品的總和的上限。
最後只需要從小到大遍歷,找到第乙個得到的經驗大於所需經驗的格仔輸出即可。
題解:
ACM 動態規劃筆記
2.解決動態規劃問題,要先找出動態轉移方程來,動態轉移方程怎麼找呢?首先得定好,用哪幾個因子,可以明確的表示好乙個狀態,然後,再通過樣例或者特例或者硬想,找出子問題和父問題的關係,或者說,子問題怎麼push,可以影響到父問題?我感覺可以放開思路想,放心大膽的想,假設你不會動態規劃,讓你暴力搜尋,你會...
學習ACM之動態規劃
分類 acm演算法 2011 06 16 22 15 145人閱讀收藏 舉報themes 優化遊戲 通過上一章的學習,相信大家對動態規劃已經有了乙個初步的了解,如果您將上一章的推薦習題全部掌握,那麼您可以開始這一章的學習內容了。這一章,我們將講解一些動態規劃的設計技巧。相信大家在做動態規劃一類題目的...
acm 動態規劃
學習參考 就是倒推 尋找遞推式 難點 然後用陣列將資料計算出來 最後直接呼叫得到答案 01揹包問題 for i 0 i 例題一 洛谷oj 開心的金明 include include using namespace std const int max 100001 long long dp max i...