Pemrograman Kompetitif · Pelajaran 9 dari 10

Strategi greedy

9 menit baca · BelajarCode

Greedy (rakus) adalah strategi mengambil pilihan yang terlihat paling baik saat ini, tanpa memikirkan akibatnya nanti. Greedy sangat cepat dan mudah ditulis, tetapi tidak selalu menghasilkan jawaban terbaik.

Contoh berhasil: uang kembalian

Untuk memberi kembalian dengan lembar sesedikit mungkin, ambil pecahan terbesar yang masih muat, berulang-ulang.

Python
1PECAHAN = [100000, 50000, 20000, 10000, 5000, 2000, 1000, 500, 200, 100]23def kembalian(jumlah):4    hasil = []5    for p in PECAHAN:6        while jumlah >= p:7            hasil.append(p)8            jumlah -= p9    return hasil1011lembar = kembalian(87600)12print(lembar)13print("Banyak lembar dan koin:", len(lembar))
Keluaran
[50000, 20000, 10000, 5000, 2000, 500, 100]
Banyak lembar dan koin: 7

Untuk susunan pecahan seperti rupiah, greedy terbukti selalu memberi jumlah lembar paling sedikit.

Contoh gagal

Bayangkan sebuah negara dengan koin 1, 3, dan 4. Untuk membayar 6:

  • Greedy mengambil 4, lalu 1, lalu 1: 3 koin.
  • Jawaban terbaik adalah 3 + 3: 2 koin.
Python
1def kembalian_greedy(jumlah, koin):2    hasil = []3    for k in sorted(koin, reverse=True):4        while jumlah >= k:5            hasil.append(k)6            jumlah -= k7    return hasil89print(kembalian_greedy(6, [1, 3, 4]))
Keluaran
[4, 1, 1]

Untuk koin sembarang, dibutuhkan teknik lain bernama dynamic programming, yang dibahas di kursus Desain dan Analisis Algoritma.

Contoh klasik: memilih kegiatan

Ada beberapa kegiatan dengan jam mulai dan jam selesai. Kamu ingin mengikuti sebanyak mungkin kegiatan tanpa bentrok. Strategi greedy yang benar: selalu pilih kegiatan yang selesai paling awal di antara yang masih bisa diikuti.

Python
1kegiatan = [(8, 10), (9, 12), (10, 11), (11, 14), (13, 15), (12, 13)]2kegiatan.sort(key=lambda k: k[1])34terpilih = []5selesai_terakhir = 06for mulai, selesai in kegiatan:7    if mulai >= selesai_terakhir:8        terpilih.append((mulai, selesai))9        selesai_terakhir = selesai10print(terpilih)
Keluaran
[(8, 10), (10, 11), (12, 13), (13, 15)]

Memilih yang selesai paling awal menyisakan waktu sebanyak mungkin untuk kegiatan berikutnya. Strategi greedy lain, seperti memilih yang mulai paling awal atau yang paling singkat, bisa gagal pada contoh tertentu.

Uji greedy sebelum percaya

Sebelum memakai greedy, cari contoh kecil yang bisa mematahkannya. Jika menemukannya, greedy itu salah. Jika tidak menemukannya, bandingkan hasilnya dengan brute force pada banyak data kecil.

Cek pemahaman

Kenapa greedy "pilih kegiatan yang mulai paling awal" bisa gagal?

Latihan

Kembalian 43.700

Pakai fungsi kembalian untuk menghitung pecahan kembalian sebesar Rp43.700, lalu tampilkan banyaknya setiap pecahan yang dipakai.

Jalankan contoh kode di pelajaran ini tanpa instalasi lewat compiler Python online.

Latih konsep ini

Tandai pelajaran ini selesai

Masuk ke aplikasi untuk mencatat kemajuan, lalu lanjutkan ke pelajaran berikutnya dari perangkat mana pun.

Buka di aplikasi