WEEK 4 • تقنيات متقدمة

Dynamic Programming

البرمجة الديناميكية

إيه هي الـ Dynamic Programming؟

💡 الفكرة الأساسية

📖 تشبيه الامتحان

تخيل إنك بتحل امتحان فيه أسئلة متشابهة:

  • الطريقة الغبية: تحل كل سؤال من الأول كل مرة
  • الطريقة الذكية (DP): تفتكر الإجابات وتستخدمها تاني!

"Don't repeat yourself" - ما تحلش نفس المشكلة مرتين!

🧩 المكونات الأساسية

1. Optimal Substructure

الحل الأمثل للمشكلة الكبيرة = تجميع حلول المشاكل الصغيرة

2. Overlapping Subproblems

نفس المشكلة الصغيرة بتتكرر كتير - نحفظها!

🔄 الطريقتين

Top-Down (Memoization)

ابدأ من المشكلة الكبيرة، احفظ النتايج

استخدم Recursion + Cache

Bottom-Up (Tabulation)

ابدأ من المشاكل الصغيرة، ابني الحل

استخدم Loop + Table

مثال: Fibonacci

المثال الكلاسيكي لفهم DP

📐 متتالية فيبوناتشي

كل رقم = مجموع الرقمين اللي قبله

0, 1, 1, 2, 3, 5, 8, 13, 21...

fib(n) = fib(n-1) + fib(n-2)

Without DP (Naive Recursion)

fib(5) calls:

fib(5) → fib(4) + fib(3)

fib(4) → fib(3) + fib(2)

fib(3) calculated TWICE! 😱

O(2ⁿ)

Exponential - بطيء جداً!

With DP (Memoization)

fib(5) with cache:

fib(5) → fib(4) + cache[3]

fib(4) → fib(3) + cache[2]

Each value calculated ONCE! ✓

O(n)

Linear - سريع جداً!

Fibonacci DP Table

Enter n and click Calculate.

مشاكل DP الشهيرة

Knapsack Problem

عندك شنطة بسعة معينة، إزاي تملاها بأغلى حاجات؟

→ سعة محدودة + قيم مختلفة

Coin Change

أقل عدد عملات تعمل بيها مبلغ معين؟

→ عملات مختلفة + مبلغ مطلوب

Longest Common Subsequence

أطول subsequence مشتركة بين كلمتين؟

→ مقارنة strings

Climbing Stairs

كام طريقة تصعد n درجة (1 أو 2 في المرة)؟

→ شبه Fibonacci!

Implementation

Top-Down (Memoization)
function fib(n, memo = {}) {
  // Base cases
  if (n <= 1) return n;
  
  // Check cache
  if (n in memo) return memo[n];
  
  // Calculate & store
  memo[n] = fib(n - 1, memo) + fib(n - 2, memo);
  return memo[n];
}

💡 الفكرة:

قبل ما نحسب، نشوف لو محسوبة قبل كده!

Bottom-Up (Tabulation)
function fib(n) {
  if (n <= 1) return n;
  
  const dp = [0, 1];
  
  for (let i = 2; i <= n; i++) {
    dp[i] = dp[i - 1] + dp[i - 2];
  }
  
  return dp[n];
}

💡 الفكرة:

نبني الجدول من الأول للآخر step by step

امتى تستخدم DP؟

🎯 علامات إن المشكلة تحتاج DP:

1. السؤال فيه كلمات زي: "أقل عدد" / "أكتر طريقة" / "كل الطرق الممكنة"
2. المشكلة ممكن تتقسم لمشاكل أصغر متشابهة (Subproblems)
3. نفس المشاكل الصغيرة بتتكرر كتير (Overlapping)
4. الحل الأمثل للكبيرة = تجميع حلول الصغيرة (Optimal Substructure)