Lời thừa số trong thời gian


12

Cho hai chuỗi , chúng tôi viết cho phép nối của chúng. Cho một xâu và số nguyên , chúng tôi viết cho phép nối của bản sao của . Bây giờ được cung cấp một chuỗi, chúng ta có thể sử dụng ký hiệu này để 'nén' nó, tức là có thể được viết là . Hãy gọi trọng lượng của một nén số ký tự xuất hiện trong nó, vì vậy trọng lượng của là hai, và trọng lượng của (một nén của ) là ba (tách rờiS1,S2S1S2Sk1(S)k=SSSkSAABAAB((A)2B)2((A)2B2)(AB)2AABABAA s được tính riêng).

Bây giờ hãy xem xét vấn đề tính toán nén 'nhẹ nhất' của một chuỗi với . Sau một số suy nghĩ, có một cách tiếp cận lập trình động rõ ràng chạy trong hoặc tùy thuộc vào cách tiếp cận chính xác.S|S|=nO(n3logn)O(n3)

Tuy nhiên, tôi đã được thông báo rằng vấn đề này có thể được giải quyết trong thời gian , mặc dù tôi không thể tìm thấy bất kỳ nguồn nào về cách thực hiện việc này. Cụ thể, vấn đề này đã được đưa ra trong một cuộc thi lập trình gần đây (vấn đề K ở đây , hai trang cuối). Trong quá trình phân tích, một thuật toán đã được trình bày, và cuối cùng, giới hạn bậc hai giả được đề cập ( ở đây ở mốc bốn phút). Đáng buồn thay, người trình bày chỉ đề cập đến 'một bổ đề tổ hợp từ phức tạp', vì vậy bây giờ tôi đã đến đây để yêu cầu giải pháp :-)O(n2logn)O(n3logn)


Chỉ là một thuộc tính ngẫu nhiên: Nếu với một chuỗi chúng ta có , thì đó cũng phải là [ Tôi đã sửa một lỗi ở đây], với có độ dài (không thể dài hơn hoặc ). Không chắc chắn làm thế nào hữu ích này mặc dù. Nếu bạn đã thấy rằng và biết rằng chứa ít nhất 2 ký tự riêng biệt và hiện đang tìm kiếm một ngắn hơn sao cho , thì bạn chỉ cần thử tiền tố của có độ dài mà chia.S = X a = Y b S = Z | S | / gcd ( | X | , | Y | ) Z gcd ( | X | , | Y | ) X Y S = X a S Y S = Y b Y X | X |SS=Xa=YbS=Z|S|/gcd(|X|,|Y|)Zgcd(|X|,|Y|)XYS=XaSYS=YbYX|X|
j_random_hacker

Vấn đề là ngay cả sau khi giảm tất cả có thể , bạn vẫn cần tổng hợp câu trả lời bằng một DP khối trên các phân đoạn (ví dụ ), vì vậy vẫn còn một số việc phải làm thêm sau đó ... D P [ l , r ] = min k D P [ l , k ] + D P [ k + 1 , r ]XaDP[l,r]=minkDP[l,k]+DP[k+1,r]
Timon Knigge 20/12/18

Tôi hiểu ý bạn là gì. Tôi nghĩ rằng bạn cần một số loại quan hệ thống trị giúp loại bỏ một số giá trị cần phải được kiểm tra - nhưng tôi chưa thể nghĩ ra một giá trị nào. Cụ thể, tôi đã xem xét như sau: Giả sử có hệ số tối ưu với ; có thể có một giải pháp tối ưu trong đó được nhân tố là với ? Thật không may, câu trả lời là có: với , có hệ số tối ưu , nhưng hệ số tối ưu duy nhất cho là .S [ 1 .. i ] S [ 1 .. i ] = X Y k k > 1 S X Y j Z j < k S = A B A B C A B C S [ 1..4 ] ( A B ) 2 S A B ( A B C ) 2kS[1..i]S[1..i]=XYkk>1SXYjZj<kS=ABABCABCS[1..4](AB)2SAB(ABC)2
j_random_hacker

Câu trả lời:


1

Nếu tôi không hiểu lầm bạn, tôi nghĩ rằng hệ số chi phí tối thiểu có thể được tính trong thời gian như sau.O(n2)

Đối với mỗi chỉ số i, chúng tôi sẽ tính toán một loạt các giá trị cho như sau. Đặt là số nguyên nhỏ nhất sao cho có số nguyên thỏa mãnĐối với cụ thể này , hãy để là lớn nhất với thuộc tính này. Nếu không có như vậy tồn tại, hãy đặt để chúng tôi biết có các giá trị zero cho chỉ mục này.(pi,ri)=1,2,pi11r2

S[irpi1+1,ipi1]=S[i(r1)pi1+1,i].
pi1ri1rpiLi=0(pi,ri)

Đặt là số nguyên nhỏ nhất lớn hơn thỏa mãn, tương tự, cho một số . Giống như trước đây, hãy lấy để trở thành số cực đại có cố định . Nói chung, là số nhỏ nhất như vậy lớn hơn . Nếu không có như vậy tồn tại, thì .pi2(ri11)pi1

S[iri2pi2+1,ipi2]=S[i(ri21)pi2+1,i]
ri22ri2pi2pi(ri11)pi1piLi=1

Lưu ý rằng với mỗi chỉ số i, chúng ta có do giá trị tăng hình học với . (nếu tồn tại, nó không chỉ lớn hơn mà còn lớn hơn ít nhất là . )Li=O(log(i+1))pipi+1(ri1)pipi/2

Giả sử bây giờ tất cả các giá trị được cung cấp cho chúng tôi. Chi phí tối thiểu được đưa ra bởi sự lặp lại với sự hiểu biết rằng đối với chúng ta đặt . Bảng có thể được điền vào thời gian .(pi,ri)

dp(i,j)=min{dp(i,j1)+1,min(dp(i,jrjpj)+dp(jrjpj+1,jpj))}
i>jdp(i,j)=+O(n2+njLj)

Chúng tôi đã quan sát ở trên rằng bằng cách ràng buộc thuật ngữ tổng theo thuật ngữ. Nhưng thực sự nếu chúng ta nhìn vào tổng số, chúng ta có thể chứng minh một cái gì đó sắc nét hơn.jLj=O(jlog(j+1))=Θ(nlogn)

Hãy xem xét cây hậu tố của đảo ngược của (tức là cây tiền tố của S). Chúng tôi sẽ tính phí mỗi đóng góp cho tổng cho một cạnh của để mỗi cạnh sẽ được tính phí nhiều nhất một lần. Sạc từng vào cạnh phát ra từ và đi về phía . Ở đây là lá của cây tiền tố tương ứng với và nca biểu thị tổ tiên chung gần nhất.T(S)SiLiT(S)pijnca(v(i),v(ipij))v(ipij)v(i)S[1..i]

Điều này cho thấy . Các giá trị có thể được tính theo thời gian bằng cách duyệt qua cây hậu tố nhưng tôi sẽ để lại chi tiết để chỉnh sửa sau nếu có ai quan tâm.O(iLi)=O(n)(pij,rij)O(n+iLi)

Hãy cho tôi biết nếu điều này có ý nghĩa.


-1

Có chuỗi S ban đầu của bạn có độ dài n. Đây là mã giả của phương thức.

next_end_bracket = n
for i in [0:n]: # main loop

    break if i >= length(S) # due to compression
    w = (next_end_bracket - i)# width to analyse

    for j in [w/2:0:-1]: # period loop, look for largest period first
        for r in [1:n]: # number of repetition loop
            if i+j*(r+1) > w:
                break r loop

            for k in [0:j-i]:
                # compare term to term and break at first difference
                if S[i+k] != S[i+r*j+k]:
                    break r loop

        if r > 1:
            # compress
            replace S[i:i+j*(r+1)] with ( S[i:i+j] )^r
            # don't forget to record end bracket...
            # and reduce w for the i-run, carrying on the j-loop for eventual smaller periods. 
            w = j-i

Tôi cố tình đưa ra ít chi tiết về "dấu ngoặc cuối" vì nó cần rất nhiều bước để xếp chồng và giải nén, điều này sẽ cho phép phương thức cốt lõi không rõ ràng. Ý tưởng là để kiểm tra một cơn co thắt cuối cùng bên trong cái đầu tiên. ví dụ ABCBCABCBC => (ABCBC) ² => (A (BC) ²) ².

Vì vậy, điểm chính là tìm kiếm thời gian lớn đầu tiên. Lưu ý rằng S [i] là thuật ngữ thứ i của S bỏ qua bất kỳ "(", ")" hoặc sức mạnh nào.

  • i-loop là O (n)
  • vòng lặp j là O (n)
  • r + k-loops là O (log (n)) vì nó dừng ở chênh lệch đầu tiên

Đây là toàn cầu O (n²log (n)).


Tôi không rõ ràng rằng các vòng lặp r và k là O (log n) - thậm chí riêng rẽ. Điều gì đảm bảo rằng sự khác biệt được tìm thấy sau nhiều lần lặp O (log n)?
j_random_hacker

Tôi có hiểu chính xác rằng bạn đang nén tham lam không? Vì điều đó không chính xác, hãy xem xét ví dụ ABABCCCABCCC mà bạn nên tính là AB (ABC ^ 3) ^ 2.
Timon Knigge

Vâng, bạn hoàn toàn đúng về điều đó, tôi đã nghĩ về điều này.
Optidad
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.