背包問題
大概的架構
一個有些規則的背包
放入一些東西找出"最好"的拿法
今天會說的
01背包
找零問題
01背包問題
一個背包大小為M的背包
要裝入n個物品(第i個物品的價值為Vi)
如何得到價值總和最大的物品
最直觀的想法
greedy算cp值?
假設有三個東西,背包總容量是6
mi=4, vi=5
mi=3, vi=3
mi=3, vi=3
那就不可行了
拿後兩個才能得到更大的價值
可以利用 (動態規劃)
開一個dp[n][m]的陣列紀錄
在拿了第i項時物品背包大小為j的價值
轉移式:dp [ i ][ j ] = max(dp [ i-1 ][ j-mi ] + vi, dp [ i-1 ] [ j ])
for(int i = 1; i <= n; i++) {
int mi, vi;
cin >> mi >> vi;
for(int j = 0; j < mi; j++) {
dp[i][j] = dp[i-1][j];
}
for(int j = mi; j <= m; j++) {
dp[i][j] = max(dp[i-1][j], dp[i-1][j-m] + v);
}
}
# PRESENTING CODE
範例
找零問題
找零問題的種類很多,在這裡以
"湊得某價位且使用最少硬幣"為例
有一個價格m
有n種錢幣,要湊到m
最少要使用幾個硬幣
其實跟剛剛的背包問題概念類似
轉移式:change[ i ][ j ] = min(change[ i-1 ][ j ], change[ i-1 ][ j-pi ] + 1]
for (int i = 0; i < n; i++)
for (int j = price[i]; j <= m; j++)
c[j] = min(c[j], c[j-price[i]] + 1);
# PRESENTING CODE
範例