첫번째는 문자열의 일정 범위가 팰린드롬인지 상수시간 내에 구할 수 있도록 전처리를 하는 작업이다. 여기선 Mancher 알고리즘을 사용했지만 DP 를 사용해도 된다. Chk() 함수의 구현부만 달라질 문이다.
두번째는 최소 문자열 분할을 구하는 작업이다. DP 로 구한다.
여기서는 내가 헤메었던 두번째 작업에 대해 설명하려고 한다.
점화식 도출
나는 처음에 위와 같은 코드를 생각했었다. 누가봐도 시간초과가 의심되는 삼중 반복문이다.
하지만 잘 생각해보면 dp2[i][j] + dp2[i+j][len-j] 부분은 중복되는 경우가 있다. dp2[i][j] 를 X 라고하고 dp2[i+j][len-j] 를 Y 라고 해보자. Y 가 만약 2개 이상의 팰린드롬으로 분해가 된다면 이는 문자열 A 와 펠린드롬인 B 로 쪼개질 수 있다. 그러면 X, Y 를 X+A, B 로 만들 수 있다. 위 코드의 마지막 반복문은 i 에서 시작하는 길이가 len 인 부분문자열을 쪼갤 수 있는 모든 경우를 셈하므로 우리가 새로 구성한 조합은 중복이 된다.
그럼 중복되는 경우를 지우는 방법이 뭐가 있을까? 간단한 방법은 문자열을 팰린드롬 + 나머지로 쪼개는 것이다. 그러면 임의의 시작점에 대해서도 dp 를 구할 필요가 없어져 시간복잡도가 O(\(\mathrm{N}^2\))
가 된다.
댓글남기기