Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 1차원 DP
- 2차원 dp
- 99클럽
- @BeforeAll
- @BeforeEach
- @Builder
- @Entity
- @GeneratedValue
- @GenericGenerator
- @NoargsConstructor
- @Query
- @Table
- @Transactional
- Actions
- Amazon EFS
- amazon fsx
- Android Studio
- ANSI SQL
- api gateway 설계
- api gateway 필터
- ApplicationEvent
- assertThat
- async/await
- AVG
- AWS
- aws eks
- AWS 프리티어
- Azure
- bind
- bitnami kafka
Archives
- Today
- Total
기록
백준_1509_팰린드롬 분할 본문
문제
1509번: 팰린드롬 분할
세준이는 어떤 문자열을 팰린드롬으로 분할하려고 한다. 예를 들어, ABACABA를 팰린드롬으로 분할하면, {A, B, A, C, A, B, A}, {A, BACAB, A}, {ABA, C, ABA}, {ABACABA}등이 있다. 분할의 개수의 최솟값을 출력하
www.acmicpc.net
풀이
1) 분할된 팰린드롬의 최소 개수
문자열 ABACA가 주어졌을 때 해당 위치 안에서 찾은 팰린드롬을 아래처럼 표현할 수 있다.
각 위치에서 분할된 펠린드롬의 최소 개수를 저장하면, 문자열 전체에서 분할된 팰린드롬의 최소 개수를 저장할 수 있다.
dp[e] = min(dp[s]+1, dp[e])
- 팰린드롬의 최소개수를 dp로 구하는 풀이(시간초과)
def isPal(s, e) :
while s<e :
if word[s] != word[e-1] : return False
s, e = s+1, e-1
return True
word = input()
size = len(word)
dp = [float('inf') for i in range(size+1)]
dp[0] = 0 # s=0일때, 0에 접함. 그래서 dp[0]을 초기화
for e in range(1, size+1) :
for s in range(e) :
if isPal(s, e):
dp[e] = min(dp[s]+1, dp[e])
print(dp[-1])
2) 팰린드롬 찾기
위 그림처럼 팰린드롬을 찾게 되면, O(N^3)의 복잡도를 가져 시간초과가 난다. 이를 해결하기 위해 팰린드롬을 판정하는 방법에 한번더 dp를 사용했다.
어떤 문자열 ABCDEF.....□ 가 주어졌을 때, 다음의 조건 하에서해당 문자열은 팰린드롬이라고 할 수 있다.
- 문자열의 처음과 끝이 같고 (A == □)
- 중간에 낀 문자열이 팰린드롬이다. (BCDEF.....이 팰린드롬)
이를 1번에 적용해보면, ABACA가 팰린드롬인지 판단하는 방법은 아래와 같다.
- 문자열의 처음과 끝이 같고 (A == A)
- 중간에 낀 문자열(BAC)이 팰린드롬인가?
여기서 다시 BAC에 대해 팰린드롬 여부를 판단해야 하는데, 이전 iteration에서 BAC에 대해 팰린드롬 여부를 판단한 적이 있다. 이를 이용해, 팰린드롬 여부를 판단할 때마다 그 값을 저장해두고 가져다 사용하면 O(N^2)로 복잡도를 줄일 수 있다.
코드
def isPal(s, e) :
if e-s == 1 : return True*1
if e-s <= 3 : return (word[s] == word[e-1])*1
return (word[s] == word[e-1]) * palBoard[s+1][e-1]
word = input()
size = len(word)
palBoard = [[1 if e-s == 1 else 0 for e in range(size+1)] for s in range(size)]
dp = [float('inf') for i in range(size+1)]
dp[0] = 0
for e in range(1, size+1) :
for s in range(e) :
palBoard[s][e] = isPal(s, e)
if palBoard[s][e] :
dp[e] = min(dp[s]+1, dp[e])
print(dp[-1])
'코딩테스트 > python' 카테고리의 다른 글
프로그래머스_요격 시스템 (0) | 2023.09.10 |
---|---|
프로그래머스_두 큐 합 같게 만들기 (0) | 2023.06.26 |
백준_1647_도시 분할 계획 (0) | 2022.10.06 |
백준_9466_텀 프로젝트 (0) | 2022.10.05 |
백준_16724_피리 부는 사나이 (0) | 2022.10.04 |
Comments