Bölüm 8: Dinamik Programlama

Bölüm 8: Dinamik Programlama · Çalışma Soruları
Temel kavramlarFibonacci0/1 sırt çantasıSınırsız sırt çantasıAlt küme toplamıEn uzun artan alt diziOrtak alt dizgi ve LCS
Sercan KÜLCÜ

Çoktan Seçmeli · Temel Kavramlar

Soru 1: DP'nin İki Özelliği

Bir problemin dinamik programlamayla verimli çözülebilmesi için hangi iki özelliği taşıması gerekir?

B: Alt problemler tekrar tekrar çağrılmalıdır (tablo işe yarar) ve optimal çözüm alt problemlerin optimal çözümlerinden kurulabilmelidir (Bellman'ın optimallik ilkesi). Açgözlü seçim özelliği açgözlü algoritmaların koşuludur; DP tüm seçenekleri dener.

Çoktan Seçmeli · Temel Kavramlar

Soru 2: Neden Tablo Gerekmez?

Birleştirme sıralaması özyinelemeli olduğu hâlde neden bir DP tablosundan yararlanmaz?

A: Diziyi ikiye bölünce iki yarı ayrık parçalardır; hiçbir alt problem tekrar çözülmez, yani saklanacak tekrar yoktur. Bu böl ve fethettir. Fibonacci'de ise fib(3) gibi alt problemler defalarca çağrılır.

Çıktı Sorusu · Fibonacci

Soru 3: Çağrı Sayısı

Düz özyinelemeli fib metoduna bir çağrı sayacı eklendi. Kod ne yazdırır? Aynı hesap derstekiler gibi bellekleme ile yapılsaydı kaç çağrı olurdu?

static int cagri = 0;
static long fib(int n) {
  cagri++;
  if (n <= 1) return n;
  return fib(n - 1) + fib(n - 2);
}
// main:
System.out.println(fib(7) + " " + cagri);
Cevabı göster
13 41
  • F(7) = 13. Çağrı sayısı 2 · F(n + 1) − 1 = 2 · 21 − 1 = 41: T(n) = T(n − 1) + T(n − 2) + 1.
  • Bellekleme ile her fib(k) en çok bir kez açılır; fib(k) iki kez çağrılır (bir kez hesap, bir kez tablodan) → 2n − 1 = 13 çağrı.

Üstelden doğrusala: Θ(φⁿ) → O(n).

Adım Adım Çalıştırma · Fibonacci

Soru 4: Bellekleme: fib(4)

Bellekleme kullanan fib(4) çağrısında bellek dizisi nasıl dolar; hangi çağrı tablodan yanıtlanır?

bellek0000001234

bellek dizisi 0 ile başlar (0 = "henüz hesaplanmadı"). fib(4) tabloda yok → fib(3) çağrılır.

bellek0000001234

fib(3) tabloda yok → fib(2) çağrılır.

bellek0000001234

fib(2) tabloda yok → fib(1) çağrılır.

bellek0000001234

fib(1): taban durum, 1 döner.

bellek0000001234

fib(2)'de a = 1; şimdi fib(0) çağrılır: taban durum, 0 döner.

bellek0010001234

bellek[2] = 1 + 0 = 1 yazılır ve döndürülür.

bellek0010001234

fib(3)'te a = 1; fib(1) çağrılır → 1 (taban).

bellek0012001234

bellek[3] = 1 + 1 = 2.

bellek0012001234

fib(4)'te a = 2; fib(2) çağrılır: bellek[2] = 1 hazır, hiç alt çağrı yapılmadan döner.

bellek0012301234

bellek[4] = 2 + 1 = 3. Toplam 7 çağrı (2n − 1); düz özyineleme 9 çağrı yapardı.

static long[] bellek = new long[50];

static long fib(int n) {
  if (n <= 1) return n;          // taban
  if (bellek[n] != 0) return bellek[n];
  long a = fib(n - 1);
  long b = fib(n - 2);
  bellek[n] = a + b;
  return bellek[n];
}

Çoktan Seçmeli · Fibonacci

Soru 5: Bellekleme ve Tablolama

Bellekleme (yukarıdan aşağı) ve tablolama (aşağıdan yukarı) için aşağıdakilerden hangisi yanlıştır?

C yanlıştır: ikisi de her alt problemi bir kez çözer ve asimptotik süreleri aynıdır; tablolama özyineleme çağrısı yapmadığı için pratikte çoğu zaman daha hızlıdır. A, B ve D derste anlatılan özelliklerdir.

Çıktı Sorusu · 0/1 Sırt Çantası

Soru 6: En Büyük Değer

Eşyalar (v, w): (10, 5), (40, 4), (30, 6), (50, 3); kapasite W = 10. 0/1 sırt çantası tablosunun son satırını, en büyük değeri ve seçilen eşyaları bulun.

Cevabı göster
iK[i][0..10]
10 0 0 0 0 10 10 10 10 10 10
20 0 0 0 40 40 40 40 40 50 50
30 0 0 0 40 40 40 40 40 50 70
40 0 0 50 50 50 50 90 90 90 90

K[4][10] = 90. Geri okuma: K[4][10] = 90 ≠ K[3][10] = 70 → eşya 4 (c = 7); K[3][7] = K[2][7] = 40 → eşya 3 yok; K[2][7] = 40 ≠ K[1][7] = 10 → eşya 2 (c = 3); K[1][3] = 0 → eşya 1 yok.

Seçim: eşya 2 + eşya 4 (40 + 50, ağırlık 7). Kalan 3 kg'a başka eşya sığmaz.

Çoktan Seçmeli · 0/1 Sırt Çantası

Soru 7: Açgözlü Neden Yanılır?

W = 10; eşyalar (değer, ağırlık): (30 ₺, 6 kg), (20 ₺, 5 kg), (20 ₺, 5 kg). Değer/ağırlık oranına göre açgözlü seçim ve optimal 0/1 çözüm kaç ₺ verir?

A: Oranlar 5, 4, 4: açgözlü önce 6 kg'lık eşyayı alır; kalan 4 kg'a 5 kg'lık eşyalar sığmaz → 30 ₺. İki 5 kg'lık eşya birlikte 10 kg, 40 ₺ eder. 50 ₺ ağırlık sınırını aşar (11 kg). Açgözlü yalnızca kesirli sırt çantasında optimaldir.

Çıktı Sorusu · 0/1 Sırt Çantası

Soru 8: Döngü Yönü

Tek eşya (değer 10, ağırlık 3) ve kapasite 9 için tek boyutlu tablo iki farklı yönde dolduruluyor. Kod ne yazdırır? Hangisi 0/1 sırt çantasıdır?

int v = 10, w = 3, W = 9;
int[] dp = new int[W + 1];
int[] dq = new int[W + 1];
for (int c = W; c >= w; c--)   // büyükten küçüğe
  dp[c] = Math.max(dp[c], v + dp[c - w]);
for (int c = w; c <= W; c++)   // küçükten büyüğe
  dq[c] = Math.max(dq[c], v + dq[c - w]);
System.out.println(dp[W] + " " + dq[W]);
Cevabı göster
10 30
  • Büyükten küçüğe: dp[c − 3] bu turda henüz güncellenmemiştir (eski satır) → eşya en çok bir kez alınır: 10 (0/1).
  • Küçükten büyüğe: dq[3] = 10, dq[6] = 10 + dq[3] = 20, dq[9] = 30 → aynı eşya üç kez alınır: 30 (sınırsız sırt çantası).

Çoktan Seçmeli · 0/1 Sırt Çantası

Soru 9: Sözde-Polinom

0/1 sırt çantası DP'si O(n · W) sürer. Bu süre neden "sözde-polinom" (pseudo-polynomial) olarak adlandırılır?

D: W = 10⁹ yalnızca 30 bitle yazılır ama tablo 10⁹ sütun ister. Süre W'nin büyüklüğüne bağlıdır, uzunluğuna değil; bu yüzden problem NP-zor kalır ve DP yalnızca W küçükken pratiktir.

Çoktan Seçmeli · Sınırsız Sırt Çantası

Soru 10: Kaç Farklı Yol?

Paralar {2, 3, 5} ile 10 tutarı kaç farklı şekilde ödenebilir? (Sıra önemsiz; dış döngü paralar üzerinde: d[x] += d[x − c].)

D: {5, 5}, {2, 3, 5}, {2, 2, 3, 3}, {2, 2, 2, 2, 2} → 4. Döngüler yer değiştirirse (dış döngü tutar üzerinde) 2 + 3 ile 3 + 2 ayrı sayılır ve sıralı diziler sayılmış olur.

Adım Adım Çalıştırma · Alt Küme Toplamı

Soru 11: altKume Tablosu

altKume({3, 4, 5, 2}, 7) tablosu satır satır nasıl dolar?

dp[i][j]012345670✓·······1 (3)2 (4)3 (5)4 (2)

a = {3, 4, 5, 2}, hedef 7. Sütun 0 hep ✓ (boş küme); satır 0'da diğer toplamlar elde edilemez.

dp[i][j]012345670✓·······1 (3)✓··✓····2 (4)3 (5)4 (2)

i = 1, x = 3: üst satır kopyalanır; dp[i−1][j−3] ✓ olan j'ler de ✓ olur. Yeni toplamlar (mavi): 3.

dp[i][j]012345670✓·······1 (3)✓··✓····2 (4)✓··✓✓··✓3 (5)4 (2)

i = 2, x = 4: üst satır kopyalanır; dp[i−1][j−4] ✓ olan j'ler de ✓ olur. Yeni toplamlar (mavi): 4, 7.

dp[i][j]012345670✓·······1 (3)✓··✓····2 (4)✓··✓✓··✓3 (5)✓··✓✓✓·✓4 (2)

i = 3, x = 5: üst satır kopyalanır; dp[i−1][j−5] ✓ olan j'ler de ✓ olur. Yeni toplamlar (mavi): 5.

dp[i][j]012345670✓·······1 (3)✓··✓····2 (4)✓··✓✓··✓3 (5)✓··✓✓✓·✓4 (2)✓·✓✓✓✓✓✓

i = 4, x = 2: üst satır kopyalanır; dp[i−1][j−2] ✓ olan j'ler de ✓ olur. Yeni toplamlar (mavi): 2, 6.

dp[i][j]012345670✓·······1 (3)✓··✓····2 (4)✓··✓✓··✓3 (5)✓··✓✓✓·✓4 (2)✓·✓✓✓✓✓✓

dp[4][7] = true. Geri okuma: dp[2][7] ✓ ama dp[1][7] · → 4 seçildi (j = 3); dp[1][3] ✓ → 3. Alt küme {3, 4}; {5, 2} de geçerlidir.

boolean altKume(int[] a, int hedef) {
  int n = a.length;
  boolean[][] dp =
      new boolean[n + 1][hedef + 1];
  for (int i = 0; i <= n; i++)
    dp[i][0] = true;           // boş küme
  for (int i = 1; i <= n; i++) {
    int x = a[i - 1];
    for (int j = 1; j <= hedef; j++)
      dp[i][j] = dp[i - 1][j]  // x alınmaz
        || (x <= j && dp[i - 1][j - x]);
  }
  return dp[n][hedef];
}

Çoktan Seçmeli · Alt Küme Toplamı

Soru 12: Eşit Bölme

{1, 5, 11, 5} dizisinin toplamı eşit iki parçaya bölünüp bölünemeyeceğini alt küme toplamıyla nasıl buluruz ve sonuç nedir?

C: Toplam S = 22; bir parça S/2 = 11 ederse diğeri de 11 eder. {11} ya da {1, 5, 5} → evet. S tek olsaydı cevap doğrudan hayır olurdu; hedef 22 tüm dizinin kendisini sorar ve bölme hakkında bilgi vermez.

Adım Adım Çalıştırma · En Uzun Artan Alt Dizi

Soru 13: lis İzleme

lis({3, 1, 4, 1, 5, 9, 2, 6}) hangi değeri döndürür?

a3141592601234567dp

dp[i]: a[i]'de biten en uzun artan alt dizinin uzunluğu. Mavi: a[j] < a[i] olan önceki adaylar.

a3141592601234567dp1

i = 0 (a = 3): önünde daha küçük öğe yok → dp[0] = 1.

a3141592601234567dp11

i = 1 (a = 1): önünde daha küçük öğe yok → dp[1] = 1.

a3141592601234567dp112

i = 2 (a = 4): adaylar 3, 1; en büyük dp j = 0 (dp = 1) → dp[2] = 2.

a3141592601234567dp1121

i = 3 (a = 1): önünde daha küçük öğe yok → dp[3] = 1.

a3141592601234567dp11213

i = 4 (a = 5): adaylar 3, 1, 4, 1; en büyük dp j = 2 (dp = 2) → dp[4] = 3.

a3141592601234567dp112134

i = 5 (a = 9): adaylar 3, 1, 4, 1, 5; en büyük dp j = 4 (dp = 3) → dp[5] = 4.

a3141592601234567dp1121342

i = 6 (a = 2): adaylar 1, 1; en büyük dp j = 1 (dp = 1) → dp[6] = 2.

a3141592601234567dp11213424

i = 7 (a = 6): adaylar 3, 1, 4, 1, 5, 2; en büyük dp j = 4 (dp = 3) → dp[7] = 4.

a3141592601234567dp11213424

Sonuç 4 = max dp (ör. 3, 4, 5, 9 ya da 1, 4, 5, 6). dp[n − 1] de 4 ama bu tesadüf; cevap her zaman en büyük dp'dir. O(n²).

static int lis(int[] a) {
  int n = a.length, enUzun = 0;
  int[] dp = new int[n];
  for (int i = 0; i < n; i++) {
    dp[i] = 1;               // tek başına
    for (int j = 0; j < i; j++)
      if (a[j] < a[i] && dp[j] + 1 > dp[i])
        dp[i] = dp[j] + 1;   // uzat
    enUzun = Math.max(enUzun, dp[i]);
  }
  return enUzun;
}

Çoktan Seçmeli · En Uzun Artan Alt Dizi

Soru 14: Cevap Hangi Hücrede?

Bir öğrenci lis metodunda enUzun yerine dp[n - 1] döndürüyor. {5, 1, 6, 2, 7, 0} için hatalı ve doğru sonuçlar nedir?

B: dp = [1, 1, 2, 2, 3, 1]. Son öğe 0 hiçbir diziyi uzatamaz → dp[5] = 1. LIS herhangi bir yerde bitebilir; doğru cevap max dp = 3 (5, 6, 7 ya da 1, 2, 7). 4 uzunluklu artan alt dizi yoktur.

Çıktı Sorusu · Ortak Alt Dizgi

Soru 15: Alt Dizgi ve Alt Dizi

"programlama" ve "gramer" için en uzun ortak alt dizgi (bitişik) ve en uzun ortak alt dizi (LCS) uzunlukları nedir? Ortak alt dizgiyi yazın; tablolardaki cevap hücreleri nerededir?

Cevabı göster
  • En uzun ortak alt dizgi: "gram", uzunluk 4 (programlama'da 3–6, gramer'de 0–3). Cevap tablonun en büyük değeridir.
  • LCS uzunluğu da 4: "gram"dan daha uzun ortak alt dizi yoktur (gramer'in kalan "er"i programlama'da m'den sonra sırayla geçmez). Cevap son hücre L[n][m]'dir.
  • Ortak alt dizgi ≤ LCS her zaman; burada eşittir. "abdca" · "cbda" örneğinde 2 ve 3'tür.

Çıktı Sorusu · En Uzun Ortak Alt Dizi

Soru 16: lcs Uzunlukları

Dersteki lcs metodu (uzunluk döndürür) ile kod ne yazdırır? Her biri için bir LCS yazın.

System.out.println(lcs("DINAMIK", "DIAMOND"));
System.out.println(lcs("ABCBDAB", "BDCABA"));
System.out.println(lcs("ABC", ""));
Cevabı göster
4
4
0
  • DINAMIK · DIAMOND: "DIAM" (D, I, A, M sırayla ikisinde de var).
  • ABCBDAB · BDCABA: "BCBA" (ya da "BDAB", "BCAB"); LCS tek değildir, uzunluğu tektir.
  • Boş dizgiyle LCS boştur: L[0][m] = 0.

Zaman ve bellek O(m · n); yalnızca uzunluk gerekiyorsa iki satırla O(min(m, n)) bellek yeter.

Adım Adım Çalıştırma · Diğer Problemler

Soru 17: Kadane İzleme

En büyük toplamlı alt dizi (Kadane, V(i) = max(a[i], V(i−1) + a[i])): kadane({2, -3, 4, -1, -2, 1, 5, -3}) ne döndürür?

a2-34-1-215-301234567V2

V(i): a[i]'de biten en büyük toplamlı alt dizinin toplamı. V(0) = a[0] = 2; enIyi = 2.

a2-34-1-215-301234567V2-1

i = 1: V = max(-3, 2 + -3) = -1 (uzat); enIyi = 2.

a2-34-1-215-301234567V2-14

i = 2: V = max(4, -1 + 4) = 4 (yeniden başla); enIyi = 4.

a2-34-1-215-301234567V2-143

i = 3: V = max(-1, 4 + -1) = 3 (uzat); enIyi = 4.

a2-34-1-215-301234567V2-1431

i = 4: V = max(-2, 3 + -2) = 1 (uzat); enIyi = 4.

a2-34-1-215-301234567V2-14312

i = 5: V = max(1, 1 + 1) = 2 (uzat); enIyi = 4.

a2-34-1-215-301234567V2-143127

i = 6: V = max(5, 2 + 5) = 7 (uzat); enIyi = 7.

a2-34-1-215-301234567V2-1431274

i = 7: V = max(-3, 7 + -3) = 4 (uzat); enIyi = 7.

a2-34-1-215-301234567V2-1431274

Sonuç 7: alt dizi [4, −1, −2, 1, 5] (indis 2–6). Her durum O(1) → O(n) zaman, O(1) bellek.

static int kadane(int[] a) {
  int enIyi = a[0], v = a[0];   // V(0)
  for (int i = 1; i < a.length; i++) {
    v = Math.max(a[i], v + a[i]);  // V(i)
    enIyi = Math.max(enIyi, v);
  }
  return enIyi;
}

Çoktan Seçmeli · Diğer Problemler

Soru 18: Matris Zinciri

Matris zinciri çarpımında M[i][j] = min { M[i][k] + M[k+1][j] + pi−1 · pk · pj : i ≤ k < j }. n matris için zaman karmaşıklığı nedir?

B: O(n²) durum (i ≤ j çiftleri), her durumda k için O(n) seçenek denenir → O(n³). Tüm parantezlemeleri denemek Catalan sayısı kadar, yani üstel sürerdi. Kural yine "durum sayısı × durum başına iş"tir.

Klasik Soru · Diğer Problemler

Soru 19: DP Tasarımı: Para Üstü

Paralar c1, …, ck ve tutar X için "en az kaç para" problemini derste anlatılan adımlarla tasarlayın: durum, bağıntı, taban durum, doldurma sırası, tablo boyutu ve karmaşıklık. Paralar {1, 3, 4} ve X = 6 için tabloyu doldurun.

Cevabı göster
  • Durum: P[x] = x tutarını ödemek için en az para sayısı.
  • Bağıntı: P[x] = 1 + min P[x − c] (c ≤ x); taban: P[0] = 0.
  • Sıra: x = 1, 2, …, X (küçük tutarlar önce hazır olmalı). Tablo: X + 1 hücre.
  • Karmaşıklık: O(k · X) zaman, O(X) bellek (sözde-polinom).
0123456P0121122

P[6] = 1 + min(P[5], P[3], P[2]) = 1 + min(2, 1, 2) = 2 (3 + 3). Açgözlü 4 + 1 + 1 = 3 para verir. Hangi paraların seçildiği, her x için kullanılan c saklanarak geri okunur.

Son

Bölüm 8: Dinamik Programlama: Çalışma Soruları
Konu anlatımı: Dinamik Programlama sunumu · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.