시간의 워드 분해


12

두 개의 문자열 주어지면 연결을 위해 를 씁니다 . 문자열이 주어 정수 , 우리는 물품 의 연결을 위해 사본 . 이제 문자열이 주어지면이 표기법을 사용하여 '압축'할 수 있습니다. 즉 는 로 작성 될 수 있습니다 . 압축 가중치는 그 안에 나타나는 문자 수를 나타내므로 의 가중치는 2이고 ( 의 압축) 의 는 3입니다 (갈라진S1,S2S1S2Sk1(S)k=SSSkSAABAAB((A)2B)2 ( ( A ) 2 B 2 ) ( A B ) 2 A A B A B A A((A)2B2)(AB)2AABABAA들)을 별도로 계산됩니다.

이제 주어진 문자열의 '가벼운'압축 컴퓨팅의 문제를 고려 함께 . 약간의 생각 후에 정확한 접근법에 따라 또는 에서 실행되는 명확한 동적 프로그래밍 접근법이 있습니다.S|S|=nO(n3logn)O(n3)

그러나이 문제를 시간에 해결할 수 있다고 들었지만이 작업을 수행하는 방법에 대한 소스를 찾을 수는 없습니다. 구체적으로,이 문제는 최근 프로그래밍 경연 대회에서 발생했습니다 (문제 K 여기 , 마지막 두 페이지). 분석하는 동안 알고리즘이 제시되었고, 마지막에 의사 2 차 경계가 언급되었습니다 ( 여기서는 4 분 표시). 슬프게도 발표자는 '복잡한 단어 조합론 정리'만을 언급 했으므로 이제 해결책을 찾기 위해 여기에 왔습니다.O(n2logn)O(n3logn)


임의의 속성 : 문자열 경우 이면 [ 는 길이가 ( 또는 보다 길 수 없음 실수를 수정했습니다 . 이것이 얼마나 유용한 지 잘 모르겠습니다. 당신은 이미 발견하는 경우 그 것을 알고 적어도 2 개 별개의 문자를 포함, 지금은 짧은 찾고있는 등이 에, 당신은 단지 접두사 시도 할 필요가 의 길이를 나누는.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

문제는 가능한 모든 줄인 후에도 서브 세그먼트에 대해 3 차 DP를 통해 답을 집계해야한다는 것입니다 (예 : ), 그래서 그 후에해야 할 일이 아직도 남아있다. D P [ l , r ] = 최소 k D P [ l , k ] + D P [ k + 1 , r ]XaDP[l,r]=minkDP[l,k]+DP[k+1,r]
Timon Knigge

무슨 말인지 알 겠어 값을 테스트 할 필요가없는 지배 관계가 필요하다고 생각합니다. 하지만 생각할 수는 없었습니다. 특히, 나는 다음을 고려했다 : 가 인 최적의 인수 분해 를 가지고 있다고 가정하자 . 가 로 인수 분해 되는 최적의 해가있을 수 있습니까? 불행하게도 대답은 '예'입니다. 경우 는 최적 인수 분해 를 갖지만 에 대한 고유 한 최적 인수 분해 는 입니다.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

답변:


1

내가 당신을 오해하지 않는다면, 최소 비용 인수 분해는 다음과 같이 시간으로 계산 될 수 있다고 생각합니다 .O(n2)

각 인덱스 i에 대해 다음과 같이 대한 여러 값 을 계산 합니다. 하자 정수가되도록 정수 최소치 만족이 특정 경우 이이 특성을 가진 가장 큰 이되게하십시오. 그러한 가 존재 하지 않으면 설정 대해 0 값이 있음을 알 수 있습니다.(pi,ri)=1,2,pi11r2

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

하자 보다 엄격하게 더 작은 정수 만족 마찬가지로 일부 입니다 . 이전과 마찬가지로 를 고정 가진 최대 값으로 사용하십시오 . 일반적으로 은 보다 엄격하게 큰 숫자 입니다. 그러한 이 입니다.pi2(ri11)pi1

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

각 인덱스 i에 대해 값이 과 함께 기하학적으로 증가 하기 때문에 있습니다. ( 이 존재하는 경우 보다 엄격하게 크지 않고 최소한 보다 큰 것입니다 . 이것은 기하학적 인 증가를 설정합니다. )Li=O(log(i+1))pipi+1(ri1)pipi/2

이제 모든 값이 우리에게 주어 졌다고 가정 하십시오. 최소 비용은 재발 에 대한 것으로 이해된다 우리가 설정 . 테이블은 시간 있습니다.(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)

우리는 이미 . 그러나 실제로 우리가 전체의 합계를 보면, 더 날카로운 것을 증명할 수 있습니다.jLj=O(jlog(j+1))=Θ(nlogn)

의 반대의 접미사 트리 (즉, 의 접두사 트리)를 고려하십시오. 우리는 합계 에 대한 각 기부금을 가장자리에 청구하여 각 가장자리에 최대 한 번 청구됩니다. 각각의 를 하고 쪽으로 이동 하는 가장자리까지 충전 하십시오 . 여기서 는 해당하는 접두사 트리의 잎 이고 nca는 가장 가까운 공통 조상을 나타냅니다.T(S)SiLiT(S)pijnca(v(i),v(ipij))v(ipij)v(i)S[1..i]

이것은 입니다. 값 은 접미사 트리의 순회를 통해 시간 에서 계산할 수 있지만 관심이있는 사람은 나중에 편집 할 세부 사항을 남겨 둡니다.O(iLi)=O(n)(pij,rij)O(n+iLi)

이것이 의미가 있는지 알려주십시오.


-1

길이가 n 인 초기 문자열 S가 있습니다. 다음은 메소드의 의사 코드입니다.

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

핵심 방법이 명확하지 않은 스택 및 언 스택에 많은 단계가 필요하기 때문에 의도적으로 "엔드 브래킷"에 대한 세부 사항을 거의 제공하지 않았습니다. 아이디어는 첫 번째 내부의 최종 수축을 테스트하는 것입니다. 예를 들어 ABCBCABCBC => (ABCBC) ² => (A (BC) ²) ².

요점은 큰 기간을 먼저 찾는 것입니다. S [i]는 "(", ")"또는 전력을 건너 뛰는 S의 i 번째 항입니다.

  • i- 루프는 O (n)입니다
  • j- 루프는 O (n)
  • r + k- 루프는 첫 번째 차이에서 멈춤에 따라 O (log (n))입니다.

이것은 전 세계적으로 O (n²log (n))입니다.


r과 k 루프가 O (log n)인지는 분명하지 않습니다. 최대 O (log n) 반복 후에 차이가 나는 것을 보장하는 것은 무엇입니까?
j_random_hacker

당신이 탐욕스럽게 압축하고 있음을 올바르게 이해하고 있습니까? 그것이 올바르지 않기 때문에, 예를 들어 ABABCCCABCCC를 고려하십시오. AB (ABC ^ 3) ^ 2로 인수 분해해야합니다.
Timon Knigge

그래, 당신은 그것에 대해 완전히 맞아, 나는 이것에 대해 생각해야합니다.
Optidad
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.