If these ideas are new, begin with:
Understand the idea
Grid DP works when allowed moves form acyclic dependencies, such as right/down. Count paths into a cell from valid predecessors; obstacles zero the affected state. Arbitrary cyclic movement is a graph-search problem instead.
Work through an example
A 3×3 right/down grid has counts [[1,1,1],[1,2,3],[1,3,6]]. Each interior count adds its top and left counts.
Time and space complexity
O(RC) time/O(C) rolling space in grid_paths; a full table O(RC).
Why it works
dp[r][c] counts exactly paths ending at that cell under the allowed moves.
Common mistakes
- An obstacle at the start must make all routes impossible.
- Reusing one row requires correct left-to-right order.
Chapter lab · Python implementation
Multiple coordinates describe subproblems involving two prefixes, grid positions, or item-and-capacity choices. Our lab computes longest common subsequence with a full table and solves 0/1 subset sum with a descending one-dimensional update. The direction of updates expresses whether an item may be reused.
This shared lab connects the chapter's topics. Follow the current lesson's worked example first, then trace the complete implementation. Additional algorithms described in topic exercises are variations you can implement independently.
def lcs(a,b):
dp=[[0]*(len(b)+1) for _ in range(len(a)+1)]
for i in range(1,len(a)+1):
for j in range(1,len(b)+1):
if a[i-1]==b[j-1]: dp[i][j]=dp[i-1][j-1]+1
else: dp[i][j]=max(dp[i-1][j],dp[i][j-1])
return dp[-1][-1],dp
def subset_sum(values,target):
if target<0 or any(x<0 for x in values):
raise ValueError('nonnegative values required')
possible=[False]*(target+1); possible[0]=True
for x in values:
for total in range(target,x-1,-1):
possible[total]=possible[total] or possible[total-x]
return possible[target]
def grid_paths(rows,cols):
if rows<1 or cols<1: return 0
dp=[1]*cols
for _ in range(1,rows):
for c in range(1,cols): dp[c]+=dp[c-1]
return dp[-1]Run and test the lab
Copy the implementation and these assertions into a Python 3 file and run it. An assertion failure means the actual result differs from the expectation. Add the current topic's exercise and boundary tests to deepen your understanding.
assert lcs('abcde','ace')[0]==3
assert lcs('','abc')[0]==0
assert subset_sum([1,5,11,5],11)
assert not subset_sum([2],4)
assert subset_sum([],0)
assert grid_paths(3,3)==6 and grid_paths(0,3)==0