Skip to content

Commit eedfb08

Browse files
authored
Merge pull request #16 from djeada/djeada-patch-2
Revise dynamic programming considerations and pitfalls
2 parents d561050 + 4bc6889 commit eedfb08

File tree

1 file changed

+52
-11
lines changed

1 file changed

+52
-11
lines changed

notes/dynamic_programming.md

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -288,30 +288,71 @@ We build a two-dimensional table $L[0..m][0..n]$ using the above recurrence.
288288

289289
**Time Complexity**: $O(mn)$
290290

291-
### Practical Considerations in Dynamic Programming
291+
### Practical Considerations
292292

293293
#### Identifying DP Problems
294294

295-
Not all problems are amenable to dynamic programming. To determine if DP is appropriate:
295+
I. If the problem asks for the number of *ways* to do something:
296296

297-
- Can the problem's optimal solution be constructed from optimal solutions to its subproblems?
298-
- Are the same subproblems being solved multiple times?
297+
* *Example:* Counting paths in a grid.
298+
* *Consequence:* Without DP, you would need to enumerate every route.
299+
300+
II. If the task is to find the *minimum* or *maximum* value under constraints:
301+
302+
* *Example:* Knapsack problem.
303+
* *Consequence:* Without DP, you would need to check every subset of items.
304+
305+
III. If the same *inputs* appear again during recursion:
306+
307+
* *Example:* Fibonacci numbers.
308+
* *Consequence:* Without DP, Fibonacci numbers would be recomputed many times.
309+
310+
IV. If the solution depends on both the *current step* and *remaining resources* (time, weight, money, length):
311+
312+
* *Example:* Scheduling tasks within a time limit.
313+
* *Consequence:* Without DP, brute force would be required.
314+
315+
V. If the problem works with *prefixes, substrings, or subsequences*:
316+
317+
* *Example:* Longest common subsequence.
318+
* *Consequence:* Without DP, exponential checking would be needed.
319+
320+
VI. If choices at each step must be explored and combined carefully:
321+
322+
* *Example:* Coin change with mixed denominations.
323+
* *Consequence:* Without DP, you cannot guarantee the fewest coins.
324+
325+
VII. If the state space can be stored in a *table or array*:
326+
327+
* *Example:* Problems with discrete states.
328+
* *Consequence:* Without this, problems with infinitely many possibilities (like arbitrary real numbers) cannot be handled.
299329

300330
#### State Design and Transition
301331

302-
- Choose variables that capture the essence of subproblems.
303-
- Clearly define how to move from one state to another.
332+
* A well-chosen *state* defines what each subproblem represents, while a poorly chosen one leaves the formulation incomplete; for example, `dp[i][w]` in the knapsack problem captures value using `i` items and capacity `w`.
333+
* A correct *transition* connects states consistently, while skipping this leads to undefined progress; in knapsack, the choice to include or exclude an item gives the formula for moving between states.
304334

305335
#### Complexity Optimization
306336

307-
- Reduce the storage requirements by identifying and storing only necessary states.
308-
- Prune unnecessary computations, possibly using techniques like memoization with pruning.
337+
* Reducing *memory usage* by discarding unnecessary states makes solutions efficient, while failing to do so can waste resources; for example, knapsack space can shrink from `O(nW)` to `O(W)` with a one-dimensional array.
338+
* Using *pruning* to skip impossible paths speeds up computation, while omitting it allows redundant work; in recursive search with memoization, branches exceeding a current best value can be safely ignored.
309339

310340
#### Common Pitfalls
311341

312-
- Leads to missing subproblems or incorrect dependencies.
313-
- Can cause incorrect results or infinite recursion.
314-
- Failing to handle special inputs can result in errors.
342+
I. Failure to Define Proper Base Cases
343+
344+
* *Example*: In grid path counting, omitting `dp[0][0] = 1` prevents any valid paths from being constructed.
345+
* *Consequence*: Without correct starting values, the DP table propagates errors and produces incorrect results.
346+
347+
II. Updating States in the Wrong Dependency Order
348+
349+
* *Example*: In knapsack with a 1D array, iterating weights from low to high causes items to be reused multiple times.
350+
* *Consequence*: Using the wrong order inflates computed values and leads to invalid or impossible solutions.
351+
352+
III. Ignoring Special or Edge Case Inputs
353+
354+
* *Example*: In knapsack, a zero-capacity input should return zero value rather than throwing an error.
355+
* *Consequence*: Overlooking edge inputs causes crashes or incorrect answers in boundary conditions.
315356

316357
### List of Problems
317358

0 commit comments

Comments
 (0)