가장 긴 상승 순서 (LIS)
LIS (가장 긴 증가 서브 시퀀스는) 가장 긴 시퀀스 상승
B1 <B2 <... <경계 필터링 시간, 우리는 호출이 순서가 상승 할 때, 순서를 양방향의 수입니다.
주어진 시퀀스 (A1을, A2, ...,에서 aN)는, 우리는 (..., AIK, AI2, AI 1) 일부 거꾸로 순서를 얻을 수 있습니다,
1 <= I1 <I2 <... <IK <= N.
예를 들어, 일부 서열을 상승 순서 (1, 7, 3, 5, 9, 4, 8), (1, 7), (3, 4, 8) 등을들 수있다.
가장 긴 길이의 시퀀스는 시퀀스 (1, 3, 5, 8)로, 4이다.
직장이 특정 시퀀스는 긴 상승 결정된 시퀀스의 길이이다.
두 알고리즘 :
하나 O (N ^ 2)
주 디자인 : DP [I] 대표적인 A [I]를 LIS 길이의 끝에서
상태 천이 : DP [I] = 최대 ( DP [I], DP [J] +1) (0 <= J <I, A [ J] <A [I])
의 경계 처리 : DP [I] = 1 ( 0 <J = <N)
코드 :
1 INT LIS () 2 { 3 INT ANS = 1 ; 4 에 대해 ( int로 I = 1 ; i가 N = <; 내가 ++ ) 5 { 6 DP [I] = 1 ; 7 대 ( INT의 J = 1 ; J <I, J ++ ) 8 { 9 경우 (a [i]를> A [J]) (10) DP [I] = 최대 (DP [I], DP [J] + 1 ); 11 } 12 } 13 대 ( INTI = 1 ; i가 = <N; ++ i가 ) 14 ANS = 최대 (ANS, DP [I]); 15 리턴 ANS; 16 }
이 : 돼지 반 +
A [I]는, i 번째의 데이터를 나타낸다.
DP는 [i]는 i의 요소의 LIS + 1 단부가 나타내는 최소 길이를 나타낸다.
상승 시퀀스에 대한 욕심 아이디어는, 그러한 LIS 자연 길이 이상 새 요소를 추가 할 수있는 더 작은의 현재 마지막 요소 분명하다.
따라서, 우리는 단지 LIS의 최소 길이는 소자의 끝 나타내는 DP 배열을 유지해야 I + 1, 즉 각자 최소 보장
이 방법은 배열의 길이 DP LIS의 길이입니다.
특정 유지 보수 절차의 DP 배열 또한 더 명확하게 설명하는 예입니다.
동일한 시퀀스에 대한 (1, 7, 3, 5, 9, 4, 8), DP 변경 프로세스는 다음과 같다 :
- DP가 [0] [0] = 1의 LIS 소자의 단부의 최소 길이 천연을 선택하지 않았다 = 첫 번째 숫자이다. (DP = {1})
- A는 [1] (7) = 들어 [1]> DP [0], 따라서 직접 (DP)의 끝에 첨가 DP [1] = A [1]. (DP = {1, 7})
- A [2] = 3, DP를 들어 [0] <A [2] <DP [1] 그래서 [2] 선택적 DP [1], DP되도록 [1] = A [2], (2)의 길이 보낸 LIS, 요소의 끝은 적게는 새로운 요소를 추가하는 것이 후속이기 때문에, 3 ~ 7도 자연스럽게 좋다. (DP = {1, 3})
- A는 [3] = 5를 들어, [3] "DP [1] 따라서, 직접 DP의 끝에 추가, [2]는 DP = A [3]. (DP = {1, 3, 5})
- A가 [4] = 9를 들면, [4] "DP [2] 따라서, 또한 DP의 단부에 직접 첨가, DP [3] = A [9]. (DP = {1, 3, 5, 9})
- A [5] = 4, DP를 들어 [1] <A [5] <DP에게 DP 5 [2] 때문에 [5] 대안 값은 [2] LIS (3) 따라서, 길이 4 요소 끝날 더 나은 것은 작은, 오보다. (DP = {1, 3, 4, 9})
- A [6] = 8, DP를 들어 [2] <A [6] <DP [3] 동일한 방법 A [6] 대안 값 DP 9 [3] 아시 이유. (DP = {1, 3, 5, 8})
이러한 서브 어레이는 DP는 어레이 LIS (4)의 필요한 길이의 길이, 완전한 DP를 유지한다.
상기 해결함으로써, 어레이는 DP가 단조롭게 증가 발견 될 수 있으므로, A [i]는 각각의 여부를 직접 어레이의 단부 (DP)에 삽입 된 것으로 결정된
즉, 마지막, 즉 어레이 DP 비교의 최대 값은, 그렇지 않다면 이상인 제 DP의 위치를 찾아 [I] 및 A [i]를 대체.
검색 시간 복잡도는 O (logN) 인 있도록이 프로세스는, 이진 검색을 이용할 수 있으므로 총 시간 복잡도는 O (N * logN)
1 INT LIS () 2 { 3 memset 함수 (DP, INF, 는 sizeof (DP)); 4 INT의 POS = 0 ; 5 DP [ 0 ] = A [ 0 ]; (6) 에 대해 ( int로 I = 1 ; i가 <; N = 내가 ++ ) 7 { 8 경우 (a [I]> DP [POS]) (9) DP [++는 POS] = A [I]; 10 다른 11 DP [LOWER_BOUND (DP, DP + POS + 1 , A [I]) - DP가] = A [I]; 12 } 13 반환 POS + 1 ; 14 }
II. 가장 긴 일반적인 서브 (LCS)
두 문자열, 동일한 문자의 일부가 형성 될 수있는 시퀀스와 동일 할 수있다, 따라서, 둘 사이의 가장 긴 공통 시퀀스의 긴 단어 시퀀스의 길이가 같은지, 동적 프로그래밍을 사용할 수있는 길이 찾아야 .
1 INT LCS () 2 { 3 memset 함수 (DP, 0 , 는 sizeof (DP)); 4 에 대해 ( int로 I = 1 ; i가 N = <; 내가 ++ ) 5 { 6 대 ( INT의 J = 1 ; J <= N; J ++ ) 7 { 8 의 경우 (a [I- 1 ] == B [J- 1 ]) (9) DP [I] [J] = 최대 (DP [I] [J], (DP) [I- 1 ] [J - 1 ] + 1 ); (10) 다른 (11) DP [I] [J] = 최대 (DP [Ⅰ- 1 ] [J], DP [I] [J = 1 ]); 12 } 13 } 14 리턴 DP [N] [N]; 15 }
III. 가장 긴 일반적인 서브 상승 (LCIS입니다)
하나 O (N ^ 3)
; 분석 [I] [J]의 단부 (B) [J]로 표현 F를 공통 시퀀스의 최대 현 길이는 [I] 전에 증가
F [I] [J] : 명백 > = F [I-1] J];
재귀 : A는 경우 [내가] = B를 [j는 ] F를 [I]은 [J]는 F [I-1의 J를! =]
만약 [I] == B [J ] : F [ I] [J] = 최대 ( F [K] [J]) + 1] (1 <= K <= J-1 && B [J]> B [K])
1 INT LCIS () 2 { 3 INT ANS = 0 ; 4 에 대해 ( int로 I = 1 난 ++; i가 N = < ) 5 { 6 대 ( INT의 J = 1 J ++; J <= N ) 7 { 8 의 경우 [(a [I] = B [J]!) DP를 I] [J]를 DP [I- = 1 ] [J 단계; (9) 다른 10 { 11 INT의 맥스 = 0 ; 12 대 ( INT에 K = 1 K <J; 케이 ++) 13 { 14 의 경우 (b의 [j를]> [K]) (B) (15) 맥스 = 최대 (맥스 (DP) [I- 1 ] [K]); 16 } 17 DP는 [I]는 [J]를 맥스 + = 1 ; 18 ANS = 최대 (DP [I] [J], ANS); 19 } 20 } 21 } 22 리턴 ANS; 23 }
2 : O (N ^ 2)
최적화이 A [I] 및 B [1-m] 시퀀스 mm 최대의 상승을 일치시키는 과정 동안 기록 업데이트 측에서 기록, 감소 된 치수를 들어
1 공극 LCIS () 2 { 3 대 ( int로 I = 1 ; i가 N = <; 내가 ++ ) -4- { 5 INT 맥스 = 0 ; 6 대 ( INT의 J = 1 ; j는 <=는 N; J ++ ) 7 { 8 DP는 [I]은 [J]를 DP [I- = 1 ] [J]을; 도 9 의 경우 (a [I]> [J] b) 10 맥스 = 최대 (맥스 (DP) [I- 1 ] [J]); 11 의 경우 (a [I] == B의 [j를]) 12 DP [I] [J]를 맥스 + = 1 ; 13 } 14 } 15 INT ANS = 0 ; (16) 에 대한이 ( int로 I = 1 난 ++; i가 N = < ) (17 개) 및 ANS = 최대 (ANS, DP [n]은 [I]); 18 리턴 ANS; 19 }