Tôi đã thấy nhiều cuộc thảo luận và nỗ lực mã khác nhau để giải quyết vấn đề "String reduction" từ interviewstreet.com, nhưng không ai trong số họ thực hiện nó thông qua lập trình động.Giải quyết thử thách "chuỗi giảm"
niêm yết dưới phần Dynamic Programming, vấn đề được mô tả như sau:
Cho một chuỗi gồm a, b và c, chúng ta có thể thực hiện các hoạt động sau đây: Lấy bất kỳ hai nhân vật riêng biệt liền kề và thay thế nó với nhân vật thứ ba. Ví dụ: nếu 'a' và 'c' liền kề, chúng có thể được thay thế bằng 'b'.
Chuỗi nhỏ nhất có thể là kết quả của việc áp dụng thao tác này nhiều lần?
Vấn đề có thể được giải quyết bằng thấu đáo tìm kiếm brute-force, tạo hiệu quả một cây của tất cả các thay thể:
// this is more or less pseudo code from my head
int GetMinLength(string s)
{
// solve edge cases
if (s.Length == 1) return 1;
if (s.Length == 2) return ReduceIfPossible(s);
// recursive brute force
int min = s.Length;
for (int i = 0; i<s.Length-1; i++)
{
if (s[i] != s[i+1])
{
var next = GetMinLength(
s.Substring(0, i) +
Reduce(s[i], s[i + 1]) +
s.Substring(i + 2)
);
if (next < min) min = next;
}
}
}
Điều này rõ ràng không cho lớn hơn N
(N <= 100
), vì vậy tôi đang cố gắng để phá vỡ nó thành các bài toán con nhỏ hơn, ghi nhớ chúng và kết hợp các kết quả.
Vấn đề là tôi không thể xác định trạng thái có "optimal substructure", cần thiết để áp dụng lập trình động (hoặc nói cách khác là "hợp nhất" kết quả từ các vấn đề phụ). Giảm thiểu một phần của chuỗi không đảm bảo rằng chuỗi cuối cùng sẽ thực sự là giải pháp nhỏ nhất.
Thuật ngữ "trạng thái" con trong trường hợp này có thể được hợp nhất vào giải pháp cuối cùng là gì?
@Dilbert Chính xác. Nhưng làm cho nó một tra cứu lồng nhau - bạn có thể tra cứu bởi một điều sau đó khác. (Bảng này là dễ nhất để tạo ra bằng cách bắt đầu từ cuối chuỗi sau đó làm việc ngược.) – btilly
Bạn có thể làm rõ bước đầu tiên hơn một chút? Tôi nghĩ rằng bạn muốn tôi xây dựng một bảng của tất cả các khối chiều dài nhỏ hơn hoặc bằng chuỗi vấn đề có thể giảm xuống một trong ba ký tự. Nhưng ý bạn là gì - bởi nhân vật bạn có gió, với vị trí bắt đầu, '? Tôi là một noob tại DP. – gautam1168
@ gautam1168 Tôi muốn nói chính xác những gì tôi đã nói. :-) Cho một ký tự cuối cùng và một vị trí bắt đầu, bạn cần một danh sách tất cả các điểm cuối của dãy mà bạn có thể thu gọn từ vị trí bắt đầu đó đến điểm cuối đó và kết thúc với ký tự đó. Điều này đòi hỏi phải giải quyết một vấn đề DP cho mỗi startpoint có thể được giải quyết nếu bạn đã giải quyết vấn đề tương tự cho tất cả những người sau này đã. (Lưu ý, bạn sẽ phải thực hiện rất nhiều việc hợp nhất các phạm vi. Tìm kiếm "hàng đợi ưu tiên" cho thứ gì đó sẽ giúp ích.) – btilly