My first Magazine pemrograman-kompetitif-dasar | Page 82
7 Dynamic Programming
Algoritma 33 Knapsack secara bottom-up dengan optimisasi flying table lebih jauh.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function SOLVE ()
d p ← new integer[G + 1]
for c ← 0, G do
d p[c] ← 0
end for
for i ← 1, N do
for c ← G down to w[i] do
d p[c] ← max(d p[c], d p[c − w[i]] + v[i])
end for
end for
return d p[G]
end function
7.2.2 Coin Change
Coin Change merupakan salah satu persoalan DP klasik. Persoalan DP Coin Change
memiliki 2 variasi. Variasi pertama adalah dengan jumlah koin tak hingga. Kita sudah mempelajari
variasi ini serta cara penyelesaiannya di subbab sebelumnya. Variasi kedua adalah jika tiap koin
hanya berjumlah satu buah, seperti yang tertera pada deskripsi soal berikut.
Contoh Soal 7.3: Coin Change
Diberikan M jenis koin, masing-masing jenis bernilai a 1 , a 2 , ..., a M rupiah. Asumsikan banyak-
nya koin untuk setiap nominal adalah satu buah. Tentukan banyaknya koin paling sedikit
untuk membayar tepat sebesar N rupiah!
Contoh
Diberikan koin-koin [1, 1, 1, 5, 5, 5, 7]. Jika kita ingin menukar 15 rupiah, solusinya adalah
dengan menggunakan tiga keping 5. Namun jika kita ingin menukar 20 rupiah, maka solusinya
adalah dengan menggunakan koin-koin 1, 1, 1, 5, 5 dan 7.
Kita tidak dapat menerapkan solusi dengan asumsi jumlah koin tak berhingga yang sudah
dijelaskan di subbab sebelumnya. Pada kasus ini, kita dapat menerapkan intuisi yang serupa
dengan persoalan Knapsack . Definisikan fungsi d p(i, c) sebagai koin minimum yang diperlukan
untuk menukar c rupiah, jika kita hanya mempunyai koin ke-1 sampai ke-i. Jika c = 0, artinya kita
ingin menukar 0 rupiah, sehingga jumlah koin minimum adalah 0. Sementara jika i = 0 dan c > 0,
artinya tidak ada koin yang tersedia untuk menukar c, sehingga d p(0, c) = ∞.
Selain base case tersebut, kita memiliki paling banyak dua pilihan, mengambil koin ke-i, atau
tidak mengambil koin ke-i. Jika kita mengambil koin ke-i, maka kita mendapatkan subpersoalan
d p(i − 1, c − a i ), sementara jika kita tidak mengambil koin ke-i, kita mendapatkan subpersoalan
d p(i − 1, c). Dari kedua kemungkinan tersebut, pilih yang memberikan nilai terkecil. Dengan
demikian, d p(i, c) dapat dirumuskan sebagai berikut:
0,
c = 0
∞,
c > 0 ∧ i = 0
d p(i, c) =
d
p(i
−
1,
c),
i
> 0 ∧ c < a i
min(d p(i − 1, c − a i ) + 1, d p(i − 1, c)), i > 0 ∧ c ≥ a i
72