9. Dinamik dasturlash
Nazariya
Fikr
Dinamik dasturlash (DD) — masalani kichik qismlarga bo‘lib, har birini
bir marta yechish va natijani saqlab qo‘yish.
Ikki shart:
- Optimal qism struktura — katta javob kichiklaridan quriladi;
- Qismlar takrorlanadi — bir xil kichik masala qayta-qayta
uchraydi (aynan shuning uchun saqlash foyda beradi).
Zinapoya
Zinapoyada n ta zina. Bir yoki ikki qadam tashlash mumkin. Necha xil
yo‘l bor?
dp = [0] * (n + 1)
dp[0] = 1
dp[1] = 1
for i in range(2, n + 1):
dp[i] = dp[i - 1] + dp[i - 2]
print(dp[n])dp[i] — i-zinaga yetishning yo‘llari soni. Bu Fibonachchi bilan bir
xil rekurrent munosabat.
DD ni qurish tartibi
- Holatni aniqlang:
dp[i]nimani anglatadi? - Bazani yozing: eng kichik holat javobi.
- O‘tishni yozing:
dp[i]oldingilaridan qanday olinadi? - Tartibni tanlang: qaysi holat oldin hisoblanishi kerak?
- Javobni ayting: qaysi katakda turadi?
Ryukzak (0/1)
W og‘irlikka sig‘adigan eng qimmat to‘plam:
dp = [0] * (W + 1)
for ogirlik, qiymat in buyumlar:
for w in range(W, ogirlik - 1, -1): # teskari!
dp[w] = max(dp[w], dp[w - ogirlik] + qiymat)
print(dp[W])Teskari yurish muhim: aks holda bitta buyum bir necha marta olinadi.
Ikki yo‘l
Pastdan yuqoriga (sikl bilan) — tezroq va xotirani boshqarish
oson. Yuqoridan pastga (rekursiya + lru_cache) — yozish oson,
holat murakkab bo‘lganda qulay.
Xotirani tejash
dp[i] faqat dp[i-1] va dp[i-2] ga bog‘liq bo‘lsa, butun massiv
shart emas — ikkita o‘zgaruvchi yetadi.
Misol
n = int(input())
a, b = 1, 1
for _ in range(n - 1):
a, b = b, a + b
print(a)
Mashq masalalari
| ✓ | Kod | Masala | Qiyinlik |
|---|---|---|---|
| AL09-1 | Zinapoya | Boshlang‘ich | |
| AL09-2 | Arzon zinapoya | Oson | |
| AL09-3 | Tanga yig‘uvchi robot | O‘rta | |
| AL09-4 | Eng uzun o‘suvchi qism | Qiyin | |
| AL09-5 | Ryukzak | Qiyin | |
| B102 | Fibonachchi sonlari | O‘rta |