DYNAMIC PROGRAMMING / ALGORITHM BRIEF

1D dynamic programming

1D dynamic programming solves problems where the state is a single index or value: dp[i] is the answer for the first i elements, or for a target amount i.

IntermediatePhase 07 / Topic 2 of 9Mental modelComplexityEdge cases
01

Overview

1D dynamic programming solves problems where the state is a single index or value: dp[i] is the answer for the first i elements, or for a target amount i. Each dp[i] is computed from a few earlier entries by a transition rule, and the final answer is dp[n] or the best over all dp[i].

Most 1D DP problems are variations of a handful of shapes: 'take or skip' (House Robber), 'last step' (Climbing Stairs), 'best ending here' (Kadane, LIS), and 'split the prefix' (Word Break, Decode Ways). Learning to recognize the shape is most of the work.

Planning a road trip day by day

Your best plan for reaching day i depends only on your best plans for a few previous days plus today's choice. Once you know the best result for each earlier day, today's best result takes a moment to compute.

02

When to use it

  • Input is a single sequence or a single number (amount, n).
  • The problem asks for a count of ways, a minimum cost, a maximum value, or feasibility.
  • Choices at each index affect only nearby earlier indexes.
  • A brute-force recursion f(i) calls f(i - 1), f(i - 2), ... repeatedly.
03

Problem patterns it solves

Take or skip with adjacency rule

Recognize it when: cannot take adjacent items: dp[i] = max(dp[i - 1], dp[i - 2] + value[i]).

  • 198. House Robber
  • 213. House Robber II
  • 740. Delete and Earn
Count ways by last step

Recognize it when: number of ways to reach n with allowed steps.

  • 70. Climbing Stairs
  • 91. Decode Ways
  • 1137. N-th Tribonacci Number
Minimum cost to reach i

Recognize it when: cheapest way to get to the end.

  • 746. Min Cost Climbing Stairs
  • 983. Minimum Cost For Tickets
  • 1025. Divisor Game
Split the prefix

Recognize it when: can s[0..i) be broken into valid pieces.

  • 139. Word Break
  • 132. Palindrome Partitioning II
  • 1043. Partition Array for Maximum Sum
Best ending at i

Recognize it when: longest or largest subsequence or subarray ending at each index.

  • 53. Maximum Subarray
  • 300. Longest Increasing Subsequence
  • 152. Maximum Product Subarray
Reachability

Recognize it when: can you reach the last index; minimum jumps.

  • 55. Jump Game
  • 45. Jump Game II
  • 1306. Jump Game III
04

Where it is used in real software

Text layout

TeX breaks paragraphs into lines by minimizing a 'badness' cost over all break points, a 1D DP over word positions.

Speech and text segmentation

Splitting text without spaces (such as Chinese or hashtags) into dictionary words is word-break DP.

Resource scheduling

Choosing non-conflicting jobs or ad slots to maximize revenue (weighted interval scheduling) is dp over sorted jobs.

Pricing and ticketing

Choosing the cheapest combination of daily, weekly, and monthly passes is the Minimum Cost For Tickets problem.

05

Key terms

dp[i]
The answer for the subproblem ending at or containing index i.
Transition
Formula for dp[i] in terms of earlier states.
Base case
dp[0] (and sometimes dp[1]) known directly.
Rolling variables
Keep only the last few dp values to use O(1) space.
06

Five-step DP method

  1. 1
    Define the state

    dp[i] = maximum money robbing houses 0..i (write it as a sentence).

  2. 2
    Find the transition

    Either skip house i (dp[i - 1]) or rob it (dp[i - 2] + nums[i]); take the max.

  3. 3
    Set base cases

    dp[0] = nums[0], dp[1] = max(nums[0], nums[1]).

  4. 4
    Choose the order

    Increasing i, so dependencies are already computed.

  5. 5
    Optimize space

    Only dp[i - 1] and dp[i - 2] are read: keep two variables.

House Robber on [2, 7, 9, 3, 1]
Step 1 / 5
2
0
1
2
3
4

STEP 1dp[0] = 2: rob the only house.

07

Decode Ways for "226"

'1' to '26' map to letters; dp[i] = ways to decode the first i characters

Step 1 / 4
iOne digit s[i-1]Two digits s[i-2..i-1]dp[i]
0--1 (empty string)
1'2' valid: + dp[0]-1
2'2' valid: + dp[1] = 1'22' valid: + dp[0] = 12
3'6' valid: + dp[2] = 2'26' valid: + dp[1] = 13

NOWi: 0 | One digit s[i-1]: - | Two digits s[i-2..i-1]: - | dp[i]: 1 (empty string)

3 decodings: BBF (2, 2, 6), BZ (2, 26), VF (22, 6). A '0' can never stand alone, and two-digit values must be between 10 and 26.

08

Implementation

function rob(nums) {  let prev2 = 0, prev1 = 0; // dp[i - 2], dp[i - 1]  for (const x of nums) {    const current = Math.max(prev1, prev2 + x);    prev2 = prev1;    prev1 = current;  }  return prev1;} // 213. House Robber II: circle, so exclude either the first or the last housefunction robCircle(nums) {  if (nums.length === 1) return nums[0];  return Math.max(rob(nums.slice(1)), rob(nums.slice(0, -1)));} function numDecodings(s) {  const dp = new Array(s.length + 1).fill(0);  dp[0] = 1;  for (let i = 1; i <= s.length; i++) {    if (s[i - 1] !== "0") dp[i] += dp[i - 1];    const two = Number(s.slice(i - 2, i));    if (i >= 2 && two >= 10 && two <= 26) dp[i] += dp[i - 2];  }  return dp[s.length];} function wordBreak(s, wordDict) {  const words = new Set(wordDict);  const dp = new Array(s.length + 1).fill(false);  dp[0] = true;  for (let i = 1; i <= s.length; i++) {    for (let j = 0; j < i; j++) {      if (dp[j] && words.has(s.slice(j, i))) {        dp[i] = true;        break;      }    }  }  return dp[s.length];}
09

Complexity and performance

Typical timeO(n)

Constant work per state.

Split-the-prefixO(n^2)

Try every split point j < i.

SpaceO(n) or O(1)

Rolling variables when only a few states are needed.

10

Trade-offs

Array vs rolling variables

The array is easier to debug and needed if you reconstruct choices; rolling variables save memory.

DP vs greedy

Some 1D problems (Jump Game, Jump Game II) have greedy solutions that are simpler; DP is the safe default when greedy is unproven.

11

Variants and related techniques

Circular arrays

Break the circle by solving twice: without the first element and without the last.

Value-indexed DP

Delete and Earn transforms to House Robber over values instead of indexes.

Reconstruct the answer

Keep a choice[] array or walk back through dp to recover which items were chosen.

12

Common mistakes

  • Off-by-one between dp indexes and input indexes.

    Fix: When dp has n + 1 entries, dp[i] usually refers to the first i elements, so the current element is s[i - 1].

  • Wrong base case for counting problems.

    Fix: The empty prefix usually has exactly 1 way.

  • Leading zeros in Decode Ways.

    Fix: '0' alone is invalid; '06' is not a valid two-digit code.

13

Interview questions

How do you find the recurrence for a 1D DP problem?

Think about the last decision: what happened at index i? Each possible last decision leads to a smaller subproblem; combine them with max, min, or sum depending on the question.

When can you reduce O(n) space to O(1)?

When dp[i] depends only on a fixed number of previous states, such as dp[i - 1] and dp[i - 2].

14

Practice problems

ProblemDifficultyWhat it trains
70. Climbing StairsEasyLast step.
198. House RobberMediumTake or skip.
213. House Robber IIMediumBreak the circle.
91. Decode WaysMediumOne or two characters.
139. Word BreakMediumSplit the prefix.
983. Minimum Cost For TicketsMediumSeveral look-backs.