Pattern · Quy hoạch động 1 chiềuTrung bình
Tên Trộm Và Dãy NhàHouse Robber
Hiểu bài
Một tên trộm đi dọc dãy nhà, mỗi nhà có lượng tiền nums[i]. Không được cướp 2 nhà liền kề (hệ thống báo động kích hoạt). Tìm số tiền tối đa có thể lấy.
Ví dụ:
ts
nums = [1, 2, 3, 1]
output = 4 // cướp nhà 0 (1) + nhà 2 (3)
nums = [2, 7, 9, 3, 1]
output = 12 // cướp nhà 0 (2) + nhà 2 (9) + nhà 4 (1)Quyết định tại mỗi nhà: cướp (lấy nums[i] + profit[i-2]) hoặc bỏ (giữ profit[i-1]).
Chọn cái lớn hơn.
Cách cơ bản
O(2ⁿ) time — mỗi nhà có 2 lựa chọn, tổng 2ⁿ nhánh đệ quyts
// Đệ quy top-down không có memoization
function robNaive(nums: number[]): number {
function dfs(i: number): number {
if (i >= nums.length) return 0
// tại nhà i: cướp hoặc bỏ
return Math.max(
nums[i] + dfs(i + 2), // cướp nhà i, nhảy sang i+2
dfs(i + 1) // bỏ nhà i, đến i+1
)
}
return dfs(0)
}Vì sao cách này chậm:
Tính lại bài toán con nhiều lần (ví dụ dfs
- được gọi từ cả dfs
- và dfs(2))
Memoization hoặc DP bottom-up khử trùng lặp này.
Mở khoá để xem lời giải tối ưu, chạy thử từng bước và câu hỏi liên quan
Xem đầy đủ chạy thử từng bước, Big-O, trường hợp biên và biến thể công ty Việt Nam.