Đối với mọi phần tử của dãy với chỉ số i
chúng tôi sẽ tính toán F(i, high)
và F(i, low)
, nơi F(i, high)
tương đương với số tiền lớn nhất của dãy với các đặc tính truy nã kết thúc bằng các yếu tố -thứ i
và yếu tố này là một "đỉnh cao" . (Tôi sẽ giải thích chủ yếu phần "cao", phần "thấp" có thể được thực hiện tương tự). Chúng tôi có thể tính toán các chức năng này bằng cách sử dụng các mối quan hệ sau:
Câu trả lời là tối đa trong số tất cả F(i, high)
và F(i, low)
giá trị.
Điều đó mang lại cho chúng tôi giải pháp lập trình động đơn giản với độ phức tạp thời gian là O(n^2)
. Nhưng chúng ta có thể đi xa hơn.
Chúng tôi có thể tối ưu hóa phép tính là max(F(j,low))
một phần. Những gì chúng tôi cần làm là tìm giá trị lớn nhất trong số F(j, low)
được tính trước đó với điều kiện là a[j] < a[i]
. Điều này có thể được thực hiện với segment trees.
Trước hết, chúng tôi sẽ "ép" chuỗi ban đầu của chúng tôi. Chúng ta cần giá trị thực của phần tử a[i]
chỉ khi tính tổng. Nhưng chúng tôi chỉ cần thứ tự tương đối của các yếu tố khi kiểm tra rằng a[j]
nhỏ hơn a[i]
. Vì vậy, chúng tôi sẽ ánh xạ mọi phần tử vào chỉ mục của nó trong mảng các phần tử đã sắp xếp mà không có bản sao. Ví dụ: trình tự a = 2 18 6 7 8 2 10
sẽ được dịch sang b = 0 5 1 2 3 0 4
. Điều này có thể được thực hiện trong O(n*log(n))
.
Yếu tố lớn nhất của b
sẽ nhỏ hơn n
, kết quả là chúng tôi có thể tạo cây phân đoạn trên đoạn [0, n]
với mỗi nút chứa tổng lớn nhất trong phân khúc (chúng tôi cần hai cây phân đoạn cho "cao" "thấp" một phần cho phù hợp). Bây giờ chúng ta hãy mô tả các bước i
của thuật toán:
- Tìm tổng lớn nhất
max_low
trên đoạn [0, b[i]-1]
sử dụng "thấp" cây phân khúc (ban đầu tất cả các nút của cây chứa zero).
F(i, high)
bằng max_low + a[i]
.
- Tìm số tiền lớn nhất
max_high
trên đoạn [b[i]+1, n]
bằng cách sử dụng cây phân đoạn "cao".
F(i, low)
bằng max_high + a[i]
.
- Cập nhật phân đoạn
[b[i], b[i]]
của cây phân đoạn "cao" với giá trị F(i, high)
tính toán lại giá trị tối đa của các nút chính (và chính là số [b[i], b[i]]
nút).
- Làm tương tự cho cây đoạn "thấp" và
F(i, low)
.
Phân tích phức tạp: b
tính toán trình tự là O(n*log(n))
. Hoạt động tối đa/cập nhật của phân đoạn có độ phức tạp O(log(n))
và có O(n)
trong số đó. Độ phức tạp tổng thể của thuật toán này là O(n*log(n))
.
Vì vậy, trong "1 3 2 7 6" số 3 có một người hàng xóm lớn hơn và nhỏ hơn? Bạn rexamples trông giống như bạn có nghĩa là "hoặc cả hai lớn hơn hoặc cả hai nhỏ hơn". – Yunnosch