İçeriğe atla
ΣDSA Patterns
Menü
Dil

Kalıp #24

Knapsack ve Alt Küme DP

İleri

Kapasite altında öğe seç veya tam toplam/hedefe vur.

Ne zaman kullanılır

Ağırlık/değerli öğelerde 0/1 seçimler, eşit alt küme bölümü, +/- ile hedef toplam.

Tanıma ipuçları

  • Eşit alt küme toplamı bölümü
  • Hedef toplam / coin change II
  • Boolean erişilebilir dp[cap]

Yaygın tuzaklar

  • 0/1 vs sınırsız döngü sırası (geriye vs ileri)
  • Toplam tek olduğunda yarım-toplam taşması
  • 1D ters yineleme yeterken 2D kullanmak

90 saniyelik tanıma egzersizi

Hangisi en iyi uyuyor?

  • Eşit alt küme toplamı bölümü
  • Hedef toplam / coin change II
  • Boolean erişilebilir dp[cap]

Interactive

Zihinsel model

Değişmezin tam adım adım anlatımı. Duraklat, noktalara tıkla veya ← → kullan. Her adımı kendi cümlelerinle anlatmayı hedefle.

Adım 1 / 8
0
1
2
3
4
5

dp[c] = best value

0/1 knapsack, capacity 5, items (2,3) and (3,4).

Nasıl düşünülür

dp[c] = kapasite c ile en iyi değer (veya erişilebilir bool). 0/1 için kapasiteyi aşağı tara ki her öğe bir kez kullanılsın. Sınırsız için yukarı tara. Alt küme-toplamı value=weight ve bool OR knapsack’tır.

Şablon şekilleri

Şekil Temel hamle Notlar
0/1 knapsack c = W..w dp[c]=max(dp[c], dp[c-w]+v)
Sınırsız c = w..W Coin, kombinasyon
Alt küme toplam bool dp Bölüm / hedef

Karmaşıklık temeli

Klasik knapsack O(n·W) zaman ve O(W) alan.

Şablondan probleme

  1. 0/1 vs sınırsız ayırt et.
  2. Kapasite W koy (sıkça sum/2).
  3. dp[0]=0 veya true; öğe başına doldur.
  4. dp[W] veya yol sayısını oku.

Şablon

TypeScript, Python ve C#’te aynı iskelet. Değişmezi uyarla; yapıyı koru.

Knapsack ve Alt Küme DP · Şablon
/** Knapsack template: partition equal subset sum (0/1 bool DP). */
export function canPartition(nums: number[]): boolean {
  const sum = nums.reduce((a, b) => a + b, 0);
  if (sum % 2) return false;
  const target = sum / 2;
  const dp = new Array<boolean>(target + 1).fill(false);
  dp[0] = true;
  for (const x of nums) {
    for (let c = target; c >= x; c--) dp[c] = dp[c]! || dp[c - x]!;
  }
  return dp[target]!;
}
/** Knapsack template: partition equal subset sum (0/1 bool DP). */
export function canPartition(nums: number[]): boolean {
  const sum = nums.reduce((a, b) => a + b, 0);
  if (sum % 2) return false;
  const target = sum / 2;
  const dp = new Array<boolean>(target + 1).fill(false);
  dp[0] = true;
  for (const x of nums) {
    for (let c = target; c >= x; c--) dp[c] = dp[c]! || dp[c - x]!;
  }
  return dp[target]!;
}
#DurumProblemTürBitti
  1. 1#416 Partition Equal Subset SumRehber
  2. 2#474 Ones and ZeroesRehber
  3. 3#494 Target SumRehber
  4. 4#518 Coin Change IIRehber
  5. 5#879 Profitable SchemesRehber
  6. 6#1049 Last Stone Weight IIRehber