25  Dinamik Programlama 2: LCS, LIS, Oyunlar

DP’yi tek diziden ötesine taşıyan üç teknik: çoklu girdide alt problem uzaylarını çarp (LCS), naif tanım çökerse bir kısıt ekleyip alt problemi genişlet (LIS), oyunlarda durumu koordinata taşı ve ben max rakip min oyna (para oyunu) — hepsi yerel kaba kuvvetle ve ebeveyn işaretçileriyle çözümün kendisini de kurtararak O(n²)

NotOturum bilgisi

Bu, DP ünitesinin ikinci dersidir. Ders 23 SRTBOT + memoization’ı tek dizide kurdu; bu ders çerçeveyi zorlayan üç klasik problemle yeni teknikleri tanıtır: LCS (en uzun ortak alt-dizilim), LIS (en uzun artan alt-dizilim) ve değişen para oyunu (alternating coin game). Temel sezgi sabit kalır: “çözümün hangi özelliğini bilsem işim biterdi?” — o özelliği yerel kaba kuvvetle dene.

25.1 Bu Derste Ne Var?

DP serisinin 2/4’ü (Erik Demaine). Üç klasik örnekle dört yeni DP fikri tanıtılır: çoklu dizi (tek değil), substring alt problemleri, ebeveyn işaretçileri (çözümü kurtarmak) ve alt problem kısıtı/genişletmesi (subproblem constraint/expansion).

“We’re now in step two out of four.” — Demaine, 0:19

Üç ana fikir:

  1. Çoklu girdi → alt problem çarpımı — iki dizi varsa, alt problem uzaylarını çarp (A’nın sonekleri × B’nin sonekleri).
  2. Alt problem kısıtı — naif tanım recurrence vermiyorsa, alt probleme bir koşul ekle (örn. “A[i] ile başla”).
  3. Subproblem expansion — kısıt için alt problem sayısını çoğalt (polinom kalmak şartıyla); oyunlarda max ile min yer değiştirir.
flowchart TD
    A["Ders 24 (L16): Dinamik Programlama 2 — LCS, LIS, Oyunlar"] --> L["LCS — çoklu girdi"]
    L --> La["alt problem uzaylarını ÇARP<br/>sonek çifti L(i,j); eşit→1+çapraz, farklı→max"]
    A --> P["Ebeveyn işaretçileri"]
    P --> Pa["seçilen yönü sakla → çözümün KENDİSİ<br/>BFS/Dijkstra ebeveyn ağacının DP karşılığı"]
    A --> I["LIS — alt problem kısıtı"]
    I --> Ia["naif çöker (artan yerel kontrol edilemez)<br/>kısıt: A[i] ile başlayan; O=max_i L(i)"]
    A --> G["Para oyunu — expansion"]
    G --> Ga["substring + kim-başlıyor koordinatı<br/>ben max, rakip min (minimax)"]
    A --> E["Subproblem expansion"]
    E --> Ea["polinom kaldığı sürece çoğalt<br/>daha çok alt problem = daha kolay recurrence"]

    classDef root fill:#fef3c7,stroke:#b45309,stroke-width:3px,color:#1f2937
    classDef branch fill:#f3f4f6,stroke:#374151,stroke-width:2px,color:#1f2937
    classDef leaf fill:#ffffff,stroke:#9ca3af,stroke-width:1px,color:#1f2937
    class A root
    class L,P,I,G,E branch
    class La,Pa,Ia,Ga,Ea leaf
Şekil 25.1: Ders 24’ün (L16) kavram haritası: kök = Dinamik Programlama 2 (Demaine) — DP serisinin 2/4’ü; DP’yi tek diziden çoklu girdiye, string’e ve oyunlara taşır. Dört dal — (1) LCS = çoklu girdi: iki dizi varsa alt problem uzaylarını ÇARP, her alt problem bir sonek çifti L(i,j); eşit harf 1 artı çapraz değiştirme argümanıyla, farklı harf max iki seçenek; O(n kare). (2) Ebeveyn işaretçileri: her alt problemde seçilen yönü sakla, L(0,0)’dan tabana yürü, çapraz adımlarda topla; DEĞER değil çözümün KENDİSİ; BFS Dijkstra ebeveyn ağacının DP karşılığı. (3) LIS = alt problem kısıtı: naif tanım çöker çünkü artan kısıtı yerel kontrol edilemez; kısıt ekle L(i) eşittir A[i] ile başlayan en uzun artan, O eşittir max i L(i); O(n kare). (4) Para oyunu = subproblem expansion: substring alt problemleri artı kim başlıyor koordinatı; ben max rakip min minimax; O(n kare). Birleştirici tema: bariz alt problemler yetmezse uzayı polinom kaldığı sürece çoğalt — daha çok alt problem eşittir daha çok kısıt eşittir daha kolay recurrence.
İpucuBuilder Notu — LCS = diff / git’in kalbi

LCS soyut bir bulmaca değil; her gün kullandığın araçların çekirdeğidir. diff ve git merge, iki dosyayı satır dizileri olarak alıp en uzun ortak alt-dizilimi bulur — eşleşen satırlar “ortak”, eşleşmeyenler “eklendi/silindi” olur. Aynı recurrence, DNA/protein hizalamasında (Needleman-Wunsch, Smith-Waterman), sürüm karşılaştırmasında ve plagiarism tespitinde yaşar. “Eşit harf → eşleştir, farklı harf → birini dışarıda bırakmayı dene” sezgisi, üç-yol birleştirmenin (three-way merge) ve edit-script üretiminin temelidir.

  • İleriye → LCS: diff/git üç-yol birleştirme, DNA/protein hizalama, sürüm karşılaştırma.
  • İleriye → LIS: patience sorting, zamanlama, kayıt-defteri analizi.
  • İleriye → minimax: değişen para oyunu = iki-oyunculu minimax; oyun yapay zekâsı (satranç, alpha-beta budama).
  • Geriye → parent pointers (BFS/Dijkstra): DP’de de çözümü ebeveyn işaretçileriyle geri kur.

Tek cümle: İki dizi varsa alt problem uzaylarını çarp; naif tanım recurrence vermiyorsa bir kısıt ekleyip alt problem sayısını genişlet (polinom kalsın); oyunlarda “ben max, rakip min” — hepsi SRTBOT + yerel kaba kuvvetle O(n²).

25.2 1. DP 2/4: Üç Örnek ve Yeni Fikirler

İlk DP dersi SRTBOT + memoization’ı kurdu. Bu ders, çerçeveyi zorlayan üç problemle yeni teknikleri tanıtır: çoklu dizi, substring, ebeveyn işaretçileri ve alt problem kısıtı/genişletmesi. Temel sezgi sabit kalır: “çözümün hangi özelliğini bilsem işim biterdi?” — o özelliği yerel kaba kuvvetle dene.

“Whenever there’s something I don’t know, I’ll just brute force it.” — Demaine, 31:58

Her problemde aynı refleks işler: bir alt problemde bilmediğin küçük bir şey varsa (hangi harf eşleşir, ikinci öğe ne, sıra kimde), o şeyin sabit veya polinom sayıda seçeneği varsa hepsini dener, alt problem çözümlerini yeniden kullanırsın.

25.3 2. SRTBOT Hatırlatma

Her DP aynı altı adımı izler: alt problemleri (dizi için prefix/suffix/substring) tanımla, bir recurrence ile ilişkilendir (alt-problem grafı DAG olmalı), topolojik sırada çöz, taban durumu ekle, orijinali kur, süreyi (\(\sum\) alt problem \(\times\) özyineleme-dışı iş) hesapla. Yeni bir alt problem türüne ihtiyaç doğdukça genişlet — polinom kaldığı sürece.

Bu derste S adımı her seferinde sınanır: tek dizinin prefix/suffix/substring’i yetmediğinde, alt problem uzayını ya çarparız (LCS), ya kısıtlarız (LIS), ya da bir koordinatla genişletiriz (para oyunu).

25.4 3. LCS: Çoklu Girdi → Alt Problem Çarpımı

Problem. İki dizi A, B verilir; ikisinin de alt-dizilimi olan en uzun diziyi bul (substring değil — aradan öğe atlanabilir). Klasik örnek: “hieroglyphology” ve “Michelangelo”.

Bowling’de tek dizi vardı; burada iki. Çözüm — çoklu girdi için genel numara:

“subproblems for multiple inputs… We just take the product, multiply the subproblem spaces.” — Demaine, 7:04

S: \(L(i, j) = A[i:]\) ve \(B[j:]\) soneklerinin LCS’i (her alt problem bir sonek çifti); \(0 \le i \le |A|\), \(0 \le j \le |B|\). Alt problem sayısı \((|A|+1) \cdot (|B|+1)\) — iki dizi için polinom; ama n dizi olsaydı \(n^n\) (üstel) olurdu.

Şekil 25.2 ders örneğini motor üzerinde gösterir: \(\mathrm{LCS}(\text{hieroglyphology}, \text{Michelangelo})\) uzunluğu 5’tir, ama optimal çözüm tekil değildir — motorun tie-break izi “iello” iken Demaine’in derste verdiği “hello” da geçerli bir ortak alt-dizilimdir (ikisi de uzunluk 5, is_subsequence ile doğrulanır). Bu önemli bir CS nüansıdır: DP’nin pin’lediği şey değerdir (uzunluk 5), tek bir temsilci dizgi değil; çözüm kümesi birden çok elemanlı olabilir.

Şekil 25.2: LCS(‘hieroglyphology’, ‘Michelangelo’) — optimal TEKİL değil, pin’lenen DEĞER (Demaine L16 §3). ÜST blok: A=hieroglyphology ve B=Michelangelo büyük harf kutuları arası ‘iello’ eşleşmeleri (motor tie-break izi, amber bağlantı çizgileri, soldan-açgözlü konumlar). ALT blok: aynı kelimeler arası ‘hello’ eşleşmeleri (Demaine’in derste verdiği ALTERNATİF optimal, soluk slate kesik çizgiler). SAĞ kutu: LCS uzunluğu = 5; optimal tekil değil — motor ‘iello’, ders ‘hello’, ikisi de geçerli ortak alt-dizilim. ALT NOT: çözüm kümesi geniş olunca pin’lenen şey DEĞER (uzunluk 5), temsilci dizgi değil. Veri MOTORDAN (assert): lcs_reconstruct(‘hieroglyphology’,‘Michelangelo’) == (‘iello’, 5); is_subsequence(‘hello’, her ikisi) True; brute_lcs_length == 5; ‘iello’ != ‘hello’ ama eşit uzunluk.

25.5 4. LCS Recurrence: Eşit / Farklı Durumlar

Çalışılan Örnek — iki durum. İlk harflere \(A[i]\) ve \(B[j]\) bakarız:

  • Farklı (\(A[i] \neq B[j]\)): ikisi birden LCS’in ilk harfi olamaz; en az biri dışarıda. Hangisi bilinmez, ikisini de dene:

    \[L(i, j) = \max\bigl( L(i+1, j),\; L(i, j+1) \bigr)\]

“at least one of Ai and Bj is not in the LCS.” — Demaine, 11:24

  • Eşit (\(A[i] = B[j]\)): bu harfi eşleştirmek her zaman optimaldir (değiştirme argümanı: çaprazlamayan bir eşleştirmede \(i\)’yi \(j\) ile eşlemek kaybettirmez), 1 puan al ve ikisinden de ilerle:

    \[L(i, j) = 1 + L(i+1, j+1)\]

T: \(i, j\) azalan. B: bir dizi tükenirse \(L = 0\). O: \(L(0, 0)\). Süre: \(\Theta(|A| \cdot |B|)\) alt problem \(\times\, O(1) = O(n^2)\).

Şekil 25.3 bu recurrence’ı küçük bir örnek üzerinde tam DP-grid olarak gösterir (\(A = \text{their}\), \(B = \text{habit}\)): her hücre \(L(i, j)\) değerini taşır; çapraz (amber) oklar eşit-harf eşleşmesini ($1 + $ çapraz), aşağı/sağ (slate) oklar farklı-harf max seçimini gösterir. \(L(0, 0) = 2\) ve ebeveyn izi LCS’in kendisini — “hi” — verir; bu §5’in konusu olan ebeveyn işaretçilerinin somut hâlidir.

Şekil 25.3: LCS sonek-çifti DP tablosu + ebeveyn izi (Demaine L16 §4-5 İMZA). A=‘their’ (satır), B=‘habit’ (sütun); her hücre L(i,j) = A[i:] ile B[j:] LCS uzunluğu. ÇAPRAZ amber ok = eşit harf (1+çapraz, değiştirme argümanı: eşleştirmek hep güvenli); AŞAĞI/SAĞ slate ok = farklı harf max(A[i] dışarıda ↓ / B[j] dışarıda →). Amber yol L(0,0)‘dan tabana ebeveyn izi; çapraz adımların harf rozetleri (amber daireler) LCS karakterleridir. Sağ üst: LCS uzunluğu = L(0,0) = 2, iz ’h → i’, LCS(‘their’,‘habit’) = ‘hi’. Veri MOTORDAN (assert): lcs_table + lcs_reconstruct; L(0,0) == 2; lcs_str == ‘hi’; is_subsequence(‘hi’, her ikisi); brute_lcs_length == 2; izden toplanan == lcs_str. Alt not: ≠ → max(2 seçenek), = → 1+çapraz; Θ(|A|·|B|).

25.6 5. Parent Pointers ile Çözüm Kurtarma

DP yalnız uzunluğu değil, LCS’in kendisini de verir. Her alt problemde “hangi seçeneği aldım?” yönünde bir ebeveyn işaretçisi (kırmızı/amber ok) çiz; sonda \(L(0,0)\)’dan tabana izleyip çapraz kenarları (harf eşleşmeleri) toplarsan LCS çıkar.

“we just follow these pointers backward… and we get our answer.” — Demaine, 21:08

Bu, BFS/Dijkstra’daki ebeveyn ağacının DP karşılığıdır; bugünkü tüm DP’lerde kullanılabilir. Kritik fark: ebeveyn işaretçisi değeri (uzunluk) değil, çözümün kendisini (dizinin/yolun kendisini) geri kurar.

Şekil 25.4 fikri iki seviyede gösterir: solda kavramsal bir \(3 \times 3\) DP-şeması (amber çapraz = topla, slate aşağı/sağ = atla; “geriye yürü, çapraz adımlarda topla”); sağda iki gerçek iz motordan — LCS “their”דhabit”in çapraz harfleri “hi”yi, LIS “carbohydrate”in ebeveyn zinciri (indeks 1→3→4→8→10) “abort”u verir. Rozet altını çizer: kaydedilen yön DEĞER değil, çözümün KENDİSİDİR.

Şekil 25.4: Ebeveyn işaretçisi: çözümü geri kurma (Demaine L16 §5, 21:08). SOL panel KAVRAM: küçük 3×3 DP-tablo şeması; her hücrede seçilen yönün ebeveyn oku (amber çapraz = TOPLA, slate aşağı/sağ = atla); L(0,0)‘dan tabana iz ’geriye yürü, çapraz adımlarda topla’. SAĞ panel İKİ GERÇEK İZ (motordan): (a) LCS ‘their’בhabit’ çapraz-adım harfleri → ‘hi’; (b) LIS ‘carbohydrate’ ebeveyn zinciri indeksleri 1→3→4→8→10 → ‘abort’. Rozet: BFS/Dijkstra ebeveyn ağacının DP karşılığı — kaydedilen yön DEĞER değil, çözümün KENDİSİ. Veri MOTORDAN (assert): lcs_reconstruct(‘their’,‘habit’) == (‘hi’, 2); çapraz harfleri ‘hi’; lis_reconstruct(‘carbohydrate’) == ([‘a’,‘b’,‘o’,‘r’,‘t’], 5); zincir indeksleri [1,3,4,8,10].

25.7 6. LIS: Naif Tanım Neden Çöker

Problem. Tek dizi; en uzun kesin artan alt-dizilim. Örnek: “carbohydrate” → “abort”.

Naif S: \(L(i) = A[i:]\)’nin en uzun artan alt-dizilimi. R denemesi: \(L(i) = \max\bigl(L(i+1),\; 1 + L(i+1)\bigr)\)çöker, çünkü “artan” kısıtı hiç uygulanmıyor; \(A[i]\)’yi eklediğimde \(L(i+1)\) zincirinin ikinci öğesinin ne olduğunu (\(A[i]\)’den büyük mü?) bilmiyoruz. “Artan” koşulunu yerel olarak kontrol edemediğimiz için recurrence yazılamaz.

Şekil 25.5 bu çöküşü ve §7’deki çözümü tek figürde toplar: üst panel naif tanımın neden recurrence vermediğini (üstü çizik deneme + “ikinci öğeyi bilmiyoruz”) gösterir; alt panel kısıtlı tanımın “carbohydrate” üzerinde nasıl çalıştığını — her harfin altında \(L(i)\) değeri ve kazanan zincir a→b→o→r→t (motordan) — verir.

25.8 7. LIS: Alt Problem Kısıtı

Çalışılan Örnek — kısıt ekleme. Çözüm: alt probleme bir koşul ekle.

“this is the idea of subproblem constraints or conditions.” — Demaine, 28:25

S (kısıtlı): \(L(i) = A[i]\) ile başlayan (yani \(A[i]\)’yi içeren) en uzun artan alt-dizilim. O: \(\max_i L(i)\) (LIS nerede başlar bilmediğimizden hepsinin maksimumu). R: \(A[i]\) kesin var; ikinci öğe \(j\)’yi bilmiyoruz, kaba kuvvetle dene (\(i < j\) ve \(A[i] < A[j]\) olan tüm \(j\)):

\[L(i) = 1 + \max\bigl( \{\, L(j) : i < j,\; A[i] < A[j] \,\} \cup \{0\} \bigr)\]

T: \(i\) azalan. B: \(L(|A|) = 0\). Süre: \(n\) alt problem \(\times\, O(n)\) özyineleme-dışı iş \(= O(n^2)\). Artan kısıtı, \(j\) seçimindeki \(A[i] < A[j]\) koşuluyla yerel olarak garanti edilir; gerisi tümevarımla artan kalır.

Şekil 25.5: LIS — naif tanım çöker, kısıtlı alt problem kurtarır (Demaine L16 §6-7 İMZA, 28:25). ÜST panel: naif tanım çöküşü — x(i)=A[i:] LIS’i deseydik denenen R = max(L(i+1), 1+L(i+1)) ÜSTÜ ÇİZİK; çünkü ikinci öğenin A[i]‘den büyük mü olduğunu BİLMİYORUZ, ’artan’ yerel kontrol edilemez. ALT panel: kısıtlı tanım — ‘carbohydrate’ 12 harf, her harf altında L(i) (motordan: [4,5,2,4,3,3,1,3,2,2,1,1]); kazanan zincir a→b→o→r→t amber oklarla (ebeveyn izi idx 1→3→4→8→10), O = max_i L(i) = 5 rozeti (i=1). Kısıt kutusu: L(i)=A[i] İLE BAŞLAYAN en uzun artan; R = 1 + max({L(j):i<j, A[i]<A[j]} ∪ {0}); n alt problem × O(n) yerel tarama = O(n²). Veri MOTORDAN (assert): lis_table(‘carbohydrate’) L birebir; lis_reconstruct == ([‘a’,‘b’,‘o’,‘r’,‘t’], 5); brute_lis_length == 5; zincir [1,3,4,8,10].

25.9 8. Değişen Para Oyunu: Substring + Genişletme

Problem. \(v_0 \ldots v_{n-1}\) değerli paralar dizisi; iki oyuncu sırayla baştaki veya sondaki parayı alır. Ben (önce başlarım) toplam değerimi maksimize etmek istiyorum. Örnek: \([5, 10, 100, 25]\) — 25’i hemen almak hata (rakip 100’ü kapar); doğrusu 5 ile başlamak, 100’ün sonunda bende kalmasını sağlamaktır.

İki uçtan silme → substring alt problemi (prefix de suffix de yetmez; iki uç da değişiyorsa neredeyse her zaman substring gerekir).

Şekil 25.6 oyunu motor üzerinde çözer: ilk hamle baş (\(v_0 = 5\)) almaktır; bu durumda toplam payım \(5 + x(1,3,\text{sen}) = 5 + 100 = 105\), oysa son (25) almak yalnız \(25 + x(0,2,\text{sen}) = 25 + 10 = 35\) verir. Bağımsız bir tanık — üçüncü koordinatsız fark formülasyonu — aynı 105’i bambaşka yoldan doğrular: \((\Sigma v + d)/2 = (140 + 70)/2 = 105\).

25.10 9. İki Oyuncu: Max/Min Recurrence

Çalışılan Örnek — subproblem expansion. Alt probleme üçüncü bir koordinat ekle: $x(i, j, p) = $ “paralar \(v_i \ldots v_j\) üzerinde, \(p\) oyuncusu başlarsa benim alacağım maksimum toplam değer” (\(p \in \{\text{ben}, \text{sen}\}\)). Bir hamle yapınca sıra döner — bu yüzden iki oyuncu durumunu izlemeliyiz.

  • \(x(i, j, \text{ben})\): baştaki (\(i\)) veya sondaki (\(j\)) parayı al, sonra sıra sende → max:

    \[x(i, j, \text{ben}) = \max\bigl( v_i + x(i+1, j, \text{sen}),\; v_j + x(i, j-1, \text{sen}) \bigr)\]

  • \(x(i, j, \text{sen})\): sen alırsın (ben puan almam, sıfır-toplam); rakip benim skorumu minimize eder:

    \[x(i, j, \text{sen}) = \min\bigl( x(i+1, j, \text{ben}),\; x(i, j-1, \text{ben}) \bigr)\]

“when you choose, we end up minimizing, because that’s the saddest thing that could happen to us.” — Demaine, 53:04

T: \(j - i\) artan. B: \(x(i, i, \text{ben}) = v_i\); \(x(i, i, \text{sen}) = 0\). O: \(x(0, n-1, \text{ben})\). Süre: \(\Theta(n^2)\) substring \(\times\, O(1) = O(n^2)\) (üçüncü koordinat alt problem sayısını yalnız 2 katına çıkarır).

Şekil 25.6: Değişen para oyunu: minimax (Demaine L16 §8-9 İMZA, 53:04). SOL panel karar ağacı: v=[5,10,100,25]; ilk hamle BAŞ al (5) → 5 + x(1,3,sen)=100 = 105 KAZANAN (amber); SON al (25) → 25 + x(0,2,sen)=10 = 35 HATA (rakip 100’ü kapar, slate). SAĞ panel recurrence kutuları: x(i,j,ben) = max(vᵢ + x(i+1,j,sen), vⱼ + x(i,j−1,sen)) parayı ben alır MAKSİMİZE; x(i,j,sen) = min(x(i+1,j,ben), x(i,j−1,ben)) sıfır-toplam rakip MİNİMİZE. Bağımsız tanık — fark formülasyonu d(i,j)=max(vᵢ−d(i+1,j), vⱼ−d(i,j−1)); (Σv+d)/2 = (140+70)/2 = 105 BİREBİR. Alt rozet: ben 105 + rakip 35 = 140 (sıfır-toplam sağlaması). substring · j−i artan · 2n² durum → O(n²). Veri MOTORDAN (assert): coin_game([5,10,100,25]) → x(0,3,ben)=105, first=‘baş’; x(1,3,sen)=100; x(0,2,sen)=10; coin_game_diff_witness == 105 BİREBİR; d(0,3)=70.

25.11 10. Subproblem Expansion İlkesi

“What we’re really doing is subproblem expansion.” — Demaine, 57:00

Bariz alt problemler (prefix/suffix/substring) yetmezse, alt problem sayısını çoğalt (polinom kaldığı sürece): bir kısıt veya durum koordinatı ekle. Para oyununda “kim başlıyor”u ekleyerek alt problemi 2 katına çıkardık; LIS’te “A[i] ile başla” kısıtını ekledik.

“The more subproblems we have, we can consider more constraints.” — Demaine, 58:25

Daha fazla alt problem = daha fazla kısıt = daha kolay recurrence. (Bir bonus: çoğu DP, bir DAG kurup üzerinde en kısa/en uzun yol çalıştırarak da çözülebilir — en uzun yol = ağırlıkları negate et + en kısa yol — ama recurrence yazmak çok daha basittir.)

Şekil 25.7 dersin birleştirici temasını tek panelde toplar: solda bariz alt problemlerin (prefix/suffix/substring) recurrence vermeye yetmediği; ortada iki çözüm yolu — kısıt ekle (LIS: “A[i] ile başlayan”; alt problem sayısı \(n = 12\) DEĞİŞMEZ) ve expansion (para: kim-başlıyor koordinatı; 10 substring × 2 = 20 giriş, motordan); sağda kural rozeti (“polinom kaldığı sürece çoğalt”) ve en uzun yol bonus köprüsü.

Şekil 25.7: Alt problem EXPANSION — dersin birleştirici teması (Demaine L16 §10, 57:00 + 58:25). SÜTUN 1 ‘bariz alt problemler YETMEZ’: prefix/suffix/substring üç mini ikon + büyük soru işareti (recurrence kapanmıyor). SÜTUN 2 iki çözüm yolu: ÜST (slate) KISIT EKLE → LIS ‘carbohydrate’, naif L(i)=A[:i] yerel kontrol edilemez, kısıt ‘A[i] ile başlayan’; alt problem sayısı n=12 DEĞİŞMEZ → LIS=‘abort’(5). ALT (amber) EXPANSION → para oyunu [5,10,100,25], substring (i,j) yetmez sıra kimde belli değil, ‘kim başlıyor’ koordinatı ben/sen ×2; 10 substring × 2 = 20 giriş. SÜTUN 3 kural rozeti: POLİNOM kaldığı sürece ÇOĞALT — daha çok alt problem = daha çok kısıt = daha kolay recurrence; bonus köprü: en uzun yol = ağırlıkları NEGATE et + en kısa yol. Veri MOTORDAN (assert): len(lis_table(‘carbohydrate’)[0])==12; lis_reconstruct==‘abort’(5); len(coin_game([5,10,100,25]))==20; distinct (i,j)==10; 10×2==20.

25.12 Bu Dersin Özeti

  1. Çoklu girdi: alt problem uzaylarını çarp (LCS: sonek çifti); 2 dizi polinom, \(n\) dizi üstel.
  2. LCS recurrence: \(A[i] \neq B[j] \to \max\)(2 seçenek); $A[i] = B[j] + $ çapraz; \(O(n^2)\).
  3. Ebeveyn işaretçileri: DP’de çözümü (uzunluk değil, dizinin kendisi) geri kur.
  4. LIS naif çöker: “artan” kısıtı uygulanamaz → alt problem kısıtı şart.
  5. Alt problem kısıtı: $L(i) = $ “\(A[i]\) ile başlayan LIS”; \(O = \max_i L(i)\); \(O(n^2)\).
  6. Para oyunu: substring + 3. koordinat (kim başlıyor); ben max, rakip min; \(O(n^2)\).
  7. Subproblem expansion: kısıt için alt problemi çoğalt (polinom kalsın).
ÖnemliTek Bir Cümle

DP 2 üç teknik ekler: çoklu girdide alt problem uzaylarını çarp (LCS), naif tanım çökerse bir kısıt ekleyip alt problemi genişlet (LIS), oyunlarda “ben max, rakip min” durumunu koordinata taşı (para oyunu) — hepsi yerel kaba kuvvetle \(O(n^2)\), ve ebeveyn işaretçileriyle yalnız değeri değil çözümün kendisini de kurtarırsın.

25.13 Kontrol Soruları

Cevap: Tek dizide prefix/suffix/substring alt problemdi; iki dizide alt problem uzaylarını çarparız — örn. A’nın sonekleri × B’nin sonekleri, yani her alt problem bir sonek çifti \(L(i, j)\). Alt problem sayısı \((|A|+1) \cdot (|B|+1) = O(n^2)\), polinom. Sabit sayıda dizi (2, 3, …) için çarpım hâlâ polinom; ama n dizi olursa alt problem sayısı \(n^n\) (üstel) olur — bu yüzden değişken sayıda dizinin LCS’i için polinom algoritma muhtemelen yoktur.

Cevap: Değiştirme (exchange) argümanı: bir optimal LCS düşün; çaprazlamayan harf-eşleştirmeleridir. \(A[i]\) ve \(B[j]\) eşitse, optimal çözümde (a) ikisi de eşleşmemişse, onları eşleyip daha uzun bir çözüm elde ederiz (çelişki); (b) \(A[i]\) başka bir şeyle eşleşmişse, onu \(B[j]\) ile eşlemeye çevirebiliriz — kayıp olmaz. Yani \(A[i]\)’yi \(B[j]\) ile eşleyen bir optimal çözüm daima vardır; o hâlde 1 puan alıp \(L(i+1, j+1)\)’e inmek güvenlidir, başka seçeneği denemeye (max almaya) gerek yoktur.

Cevap: Naif tanımda \(A[i]\)’yi çözüme katmak istediğimizde, kalan \(L(i+1)\)’in ilk öğesinin ne olduğunu bilmeyiz — $A[i] < $ (o öğe) mi? “Artan” koşulunu yerel olarak kontrol edemeyiz, recurrence yazılamaz. Çözüm: alt probleme kısıt ekle — $L(i) = $ “\(A[i]\) ile başlayan” LIS. Artık \(A[i]\) kesin dahildir; ikinci öğe \(j\)’yi kaba kuvvetle (\(i < j\) ve \(A[i] < A[j]\) olan tüm \(j\)) deneriz, böylece artan koşulu yerel olarak garanti edilir. Orijinal problem artık \(L(0)\) değil, \(\max_i L(i)\) (LIS nerede başlar bilinmez).

Cevap: Oyun sıfır-toplamdır: rakip kendi skorunu maksimize ederken benim skorumu minimize eder. $x(i, j, ) = $ “sen başlarsan benim alacağım max değer” olduğundan, rakibin hamlesini kontrol edemem; en kötü (benim için en az) durumu varsaymalıyım → min. Ben seçtiğimde max, rakip seçtiğinde min — klasik minimax. “Subproblem expansion”: alt probleme üçüncü koordinat (kim başlıyor: ben/sen) ekleyerek alt problem sayısını 2 katına çıkardık; bu, “hamle sonrası sıra döner” durumunu temsil edip recurrence’ı çok sadeleştirdi (polinom kaldı: \(2 \cdot n^2\) alt problem).

25.14 Egzersizler

Egzersiz 1. LCS’i bir grid (DAG) olarak çiz (örn. “their” vs “habit”); çapraz kenarların eşleşme, diğerlerinin max olduğunu ve ebeveyn izinin LCS’i verdiğini göster.

Egzersiz 2. LIS’i Python’da yaz (kısıtlı alt problem); “carbohydrate” gibi bir örnekte \(L(i)\) tablosunu doldur.

Egzersiz 3. LCS recurrence’ının eşit-harf durumunu ($1 + $ çapraz) değiştirme argümanıyla kanıtla.

Egzersiz 4. Para oyununu \([5, 10, 100, 25]\) üzerinde \(x(i, j, \text{ben}/\text{sen})\) matrisiyle elle çöz; optimal stratejiyi ebeveyn izinden çıkar.

Egzersiz 5. LIS’i DAG en kısa yola indirge: çapraz kenarlara \(-1\), diğerlerine \(0\) ver; en kısa yolun en uzun artan alt-dizilime karşılık geldiğini göster.

25.15 Sonraki Ders İçin Hazırlık

UyarıSonraki: Ders 25 (PS8) — Problem Oturumu 8 (DP uygulamaları)

Ders 25 (PS8): Problem Oturumu 8 (DP uygulamaları). Bir problem oturumuyla DP’yi pekiştiriyoruz: bu derste öğrenilen çoklu girdi, alt problem kısıtı ve genişletme tekniklerini gerçek problemlerde uygulayacağız. SRTBOT disiplini ve “yerel kaba kuvvet” sezgisi merkezde kalır. Hoca değişimi notu: problem oturumlarını Justin Solomon yürütür (DP ders bloğu Demaine’in; PS8 Solomon’un oturumudur). DP ünitesi Ders 24-27 (L16-L18) boyunca devam eder ve Ders 30 = PS10/Quiz 3 Gözden Geçirme ile özetlenir.

Ders 25 Öncesi Yapılacak:

  • Bu dersin egzersizlerini, özellikle Egzersiz 2 (LIS) ve 4 (para oyunu) çöz.
  • LCS, LIS ve para oyununun SRTBOT’unu ezberden yaz.
  • Ana cümleyi tekrar oku: “Bilmediğin şeyi kaba kuvvetle dene; kısıt için alt problemi genişlet.”

25.16 Anahtar Kavramlar (Cheat Sheet)

Kavram Tanım Sayfada
Çoklu girdi Alt problem uzaylarını çarp (sonek × sonek) Böl. 3
LCS recurrence \(\neq \to \max\)(2); $= + $ çapraz; \(O(n^2)\) Böl. 4
Ebeveyn işaretçileri DP çözümünü (dizinin kendisi) geri kur Böl. 5
Alt problem kısıtı \(L(i) = A[i]\) ile başlayan LIS; \(O = \max_i L(i)\) Böl. 7
LIS recurrence \(1 + \max\{L(j) : i < j,\, A[i] < A[j]\}\); \(O(n^2)\) Böl. 7
Para oyunu \(x(i, j, p)\); ben max, rakip min; substring Böl. 9
Minimax Ben seçince max, rakip seçince min Böl. 9
Subproblem expansion Kısıt için alt problemi çoğalt (polinom) Böl. 10

25.17 Builder ve OMSCS Bağlantıları

İpucu6 köprü

Bu dersin üç tekniği — çoklu girdi çarpımı, alt problem kısıtı, subproblem expansion — ML ve sistem mühendisliğindeki çok sayıda araca doğrudan bağlanır; köprülerin özeti:

  1. LCSdiff/git üç-yol birleştirme, DNA/protein hizalama, plagiarism tespiti, edit-distance.
  2. LIS → patience sorting (LIS’i \(O(n \log n)\)’e indiren kart-yığma algoritması), zamanlama, en uzun uyumlu kayıt dizisi.
  3. Minimax (para oyunu) → oyun yapay zekâsı (satranç, go); alpha-beta budama minimax ağacını gereksiz dalları keserek hızlandırır — para oyununun max/min recurrence’ının doğrudan genişlemesi.
  4. Ebeveyn işaretçileri → çözüm rekonstrüksiyonu: hizalama, rota, düzenleme betiği (edit script); değil değer, çözümün kendisi.
  5. Subproblem expansion → durum-augmentasyonu; OMSCS CS 6515’te DP tasarımının kalbi — her DP probleminde “bariz alt problem yetmiyorsa hangi koordinatı eklerim?” refleksi.
  6. Çoklu girdi çarpımı → çok boyutlu DP tabloları; sabit-boyut çarpım polinom, \(n\)-boyut üstel.

ÖnemliTek bir şey alıp gideceksen

DP 2, tek diziden ötesine geçer. İki dizi varsa alt problem uzaylarını çarp (LCS). Naif tanım recurrence vermiyorsa bir kısıt ekleyip alt problemi genişlet (LIS: “A[i] ile başla”). Oyunlarda durumu (kim başlıyor) koordinata taşı; ben max, rakip min (minimax). Bilmediğin her şeyi yerel kaba kuvvetle dener, alt problemleri yeniden kullanırsın — hepsi polinom (\(O(n^2)\)). Ve ebeveyn işaretçileriyle yalnız değeri değil, çözümün kendisini de kurtarırsın.