20 bài toán kinh điển trong lập trình
Dưới đây là danh sách 20 bài toán quy hoạch động kinh điển trong lập trình:
- Tìm kiếm đường đi ngắn nhất trong đồ thị (Shortest Path in Graph)
- Tìm chuỗi con không giảm dài nhất (Longest Increasing Subsequence)
- Tìm cách cắt que tính sao cho giá trị lợi nhuận là lớn nhất (Rod Cutting)
- Tìm tổng lớn nhất của các phần tử trong mảng con liên tiếp (Maximum Subarray Sum)
- Tìm số lần tối thiểu để đổi tiền (Coin Change)
- Tìm cách sắp xếp các phần tử sao cho tổng các phần tử đôi một không giao nhau là lớn nhất (Maximum Sum of Non-adjacent Elements)
- Tìm cách xếp ba lô sao cho giá trị của các vật phẩm là lớn nhất (Knapsack)
- Tìm cách xếp hàng rào sao cho độ dài của các tấm ván là lớn nhất (Fence Repair)
- Tìm cách xếp hàng hóa sao cho khối lượng là lớn nhất (Multiple Knapsack)
- Tìm cách đặt các quân mã sao cho chúng không ăn nhau (N-Queens Problem)
- Tìm cách chia sẻ công việc sao cho tổng thời gian hoàn thành là nhỏ nhất (Job Scheduling)
- Tìm cách chia nhỏ một số sao cho tổng số lượng số là nhỏ nhất (Minimum Number of Squares)
- Tìm cách tách một xâu con ra khỏi một xâu sao cho tổng trọng số của các xâu con là lớn nhất (Maximum Weighted Independent Set)
- Tìm cách tách một xâu ra thành các xâu con đối xứng (Longest Palindromic Subsequence)
- Tìm cách chia nhỏ một dãy số sao cho tổng độ chênh lệch giữa các phần tử là nhỏ nhất (Partition Problem)
- Tìm cách chia sẻ số điểm trên trục số thành các đoạn sao cho số lượng đoạn là nhỏ nhất (Minimum Range Cover)
- Tìm cách chọn một số phần tử trong một tập hợp sao cho tổng của chúng bằng một số cho trước (Subset Sum)
- Tìm cách sắp xếp các phần tử sao cho chúng tạo thành một số lớn nhất (Largest Number)
- Tìm cách xây dựng một cây khung nhỏ nhất trong đồ thị (Minimum Spanning Tree)
- Tìm cách chia sẻ một tập hợp thành các phân hoạch sao cho tổng sự khác biệt giữa các phân hoạch là nhỏ nhất (Minimum Partition)
Cách giải quyết các bài toán quy hoạch động
Tất cả các bài toán quy hoạch động đều có thể giải quyết bằng cách sử dụng cùng một phương pháp, đó là phương pháp lập bảng (table-filling) hoặc cách tiếp cận theo đệ quy. Dưới đây là một số bài toán quy hoạch động phổ biến và cách giải quyết chúng:
-
Tìm kiếm đường đi ngắn nhất trong đồ thị (Shortest Path in Graph)
Cách giải quyết: Sử dụng thuật toán Dijkstra hoặc thuật toán Bellman-Ford để tìm kiếm đường đi ngắn nhất trong đồ thị.
-
Tìm chuỗi con không giảm dài nhất (Longest Increasing Subsequence)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm chuỗi con không giảm dài nhất.
-
Tìm cách cắt que tính sao cho giá trị lợi nhuận là lớn nhất (Rod Cutting)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm cách cắt que tính sao cho giá trị lợi nhuận là lớn nhất.
-
Tìm tổng lớn nhất của các phần tử trong mảng con liên tiếp (Maximum Subarray Sum)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm tổng lớn nhất của các phần tử trong mảng con liên tiếp.
-
Tìm số lần tối thiểu để đổi tiền (Coin Change)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm số lần tối thiểu để đổi tiền.
-
Tìm cách sắp xếp các phần tử sao cho tổng các phần tử đôi một không giao nhau là lớn nhất (Maximum Sum of Non-adjacent Elements). Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm cách sắp xếp các phần tử sao cho tổng các phần tử đôi một không giao nhau là lớn nhất.
- Tìm cách xếp ba lô sao cho giá trị của các vật phẩm là lớn nhất (Knapsack)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm cách xếp các vật phẩm vào ba lô sao cho giá trị của chúng là lớn nhất có thể.
-
Tìm cách phân chia các công việc sao cho tổng giá trị là lớn nhất (Job Scheduling)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm cách phân chia các công việc sao cho tổng giá trị là lớn nhất.
-
Tìm đường đi ngắn nhất giữa hai đỉnh trong đồ thị không có trọng số (Shortest Path in Unweighted Graph)
Cách giải quyết: Sử dụng thuật toán BFS để tìm đường đi ngắn nhất giữa hai đỉnh trong đồ thị không có trọng số.
-
Tìm cách xây dựng cây khung nhỏ nhất trong đồ thị (Minimum Spanning Tree)
Cách giải quyết: Sử dụng thuật toán Prim hoặc thuật toán Kruskal để tìm cách xây dựng cây khung nhỏ nhất trong đồ thị.
- Tìm cách chia một chuỗi thành các từ sao cho tổng chi phí là nhỏ nhất (Word Break)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm cách chia một chuỗi thành các từ sao cho tổng chi phí là nhỏ nhất.
- Tìm cách tạo ra một số lớn nhất từ một số lượng số đã cho (Largest Number)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm cách tạo ra một số lớn nhất từ một số lượng số đã cho.
- Tìm số đường đi khác nhau từ một điểm đến điểm khác trong một lưới (Number of Paths in Grid)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm số đường đi khác nhau từ một điểm đến điểm khác trong một lưới.
- Tìm cách sắp xếp một mảng sao cho tổng giá trị của mảng kết quả là lớn nhất (Maximum Sum Increasing Subsequence)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm cách sắp xếp một mảng sao cho tổng giá trị của mảng kết quả là lớn nhất.
- Tìm số dãy con liên tiếp có tổng lớn nhất (Maximum Subarray)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm số dãy con liên tiếp có tổng lớn nhất.
- Tìm số lượng đường đi ngắn nhất từ một đỉnh đến tất cả các đỉnh khác trong đồ thị có trọng số dương (All Pairs Shortest Path)
Cách giải quyết: Sử dụng thuật toán Floyd-Warshall để tìm số lượng đường đi ngắn nhất từ một đỉnh đến tất cả các đỉnh khác trong đồ thị có trọng số dương.
- Tìm cách sắp xếp một dãy sao cho số lần đổi chỗ ít nhất (Minimum Swaps)
Cách giải quyết: Sử dụng thuật toán Bubble Sort hoặc Selection Sort để tìm cách sắp xếp một dãy sao cho số lần đổi chỗ ít nhất.
- Tìm cách sắp xếp một dãy sao cho tổng giá trị của các phần tử liên tiếp là lớn nhất (Maximum Sum Subarray)
Cách giải quyết: Sử dụng thuật toán Kadane để tìm cách sắp xếp một dãy sao cho tổng giá trị của các phần tử liên tiếp là lớn nhất.
- Tìm số cách để tạo ra một số đã cho bằng cách sử dụng các số đã cho (Number of Ways to Make Change)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm số cách để tạo ra một số đã cho bằng cách sử dụng các số đã cho.
- Tìm số lượng dãy con không giảm dài nhất trong một mảng (Longest Increasing Subsequence)
Cách giải quyết: Sử dụng cách tiếp cận theo đệ quy hoặc phương pháp lập bảng để tìm số lượng dãy con không giảm dài nhất trong một mảng.