Dynamic Programming (DP) là một kỹ thuật lập trình được sử dụng để giải quyết các bài toán phức tạp bằng cách chia nhỏ chúng thành các bài toán con đơn giản hơn và lưu trữ kết quả của các bài toán con để tránh tính toán lại nhiều lần. ...Đọc tiếp...

DP thường được áp dụng trong các bài toán tối ưu hóa và có thể được phân loại thành hai loại chính:

1. Top-Down Approach (Memoization)

  • Cách làm: Bắt đầu từ bài toán gốc và phân chia thành các bài toán con. Khi giải quyết từng bài toán con, lưu trữ kết quả vào một bảng (mảng hoặc dictionary) để tái sử dụng sau này.
  • Ưu điểm: Dễ dàng triển khai và hiểu, thường được viết dưới dạng đệ quy.
  • Nhược điểm: Có thể tiêu tốn nhiều bộ nhớ nếu có nhiều bài toán con khác nhau.

2. Bottom-Up Approach (Tabulation)

  • Cách làm: Xây dựng một bảng (mảng) từ dưới lên. Giải quyết tất cả các bài toán con trước khi giải quyết bài toán gốc.
  • Ưu điểm: Tối ưu hơn về bộ nhớ và tốc độ, vì không cần đệ quy và không có overhead của cuộc gọi hàm.
  • Nhược điểm: Có thể khó khăn hơn để triển khai so với phương pháp top-down.

Ứng Dụng

Dynamic Programming thường được sử dụng trong các bài toán như:

  • Fibonacci Sequence: Tính số Fibonacci n-th.
  • Knapsack Problem: Tối ưu hóa trọng lượng và giá trị của các vật phẩm.
  • Longest Common Subsequence: Tìm chuỗi con chung dài nhất giữa hai chuỗi.
  • Edit Distance: Tính khoảng cách chỉnh sửa giữa hai chuỗi.

Tính Chất

  • Optimal Substructure: Bài toán lớn có thể được giải quyết thông qua giải pháp tối ưu của các bài toán con.
  • Overlapping Subproblems: Các bài toán con lặp lại và có thể được lưu trữ để giảm bớt tính toán lại.

Dynamic Programming là một công cụ mạnh mẽ trong lập trình, giúp tối ưu hóa thời gian và không gian trong nhiều bài toán phức tạp.