본문 바로가기
Python/백준 문제 풀이

[BOJ] 7977번 크리스 마틴

by 서원두 2022. 11. 10.

[BOJ] 7977번 크리스 마틴 문제

굉장히 흥미로웠던 문제다. 이 문제를 알기 위해서는 최장 공통 부분 수열(LCS; Longest Common Subsequence)를 알아야한다. 몰라도 어찌어찌 풀 수는 있겠지만, 당연하게도 LCS 알고리즘을 알면 풀기 더 쉽다.


LCS 알고리즘은 두 개의 길이가 다른 문자열이 있을 때, 공통적으로 존재하는 최대 부분 문자열을 구하는 알고리즘이다. 정확히는 다이나믹 프로그래밍(Dynamic Programming)의 일종이며, 그림을 보면서 이해하기가 쉽기 때문에 그렇게 막 어려운 알고리즘은 아니다.

이 알고리즘의 핵심은 같은 문자일 때에는 모든 방향에서의 이전 DP 값에서 1을 더한 값을 저장하고, 아닌 경우에는 인접한 두 값 중 큰 값을 저장한다는 것이다. 우리는 이걸 이 문제에 잘 이용해야한다.

이 문제의 핵심은 이 LCS 알고리즘을 적용시켰을 때 유사도가 가장 적은, 즉 최대 LCS의 값이 적은 문자열을 만들어내야 한다는 것이다.

결국 이 조건을 만족하는 문자열은 입력으로 주어진 문자열 중에서 가장 적은 개수의 문자만으로 이루어진 문자열이 되고, 만족하는 길이 n은 해당 문자가 입력의 문자열에 있는 개수가 된다.

예시로 주어진 'GACT'에 대한 정답은 n = 1이며, 'AAAA', 'TTTT', 'GGGG', 'CCCC' 모두 정답이 된다. 잘 이해가 안된다면 LCS 알고리즘을 조금 더 공부하고 고민해보자.

import sys

if __name__ == '__main__':
    N = int(sys.stdin.readline().rstrip())
    dna = sys.stdin.readline().rstrip()
    atgc = [dna.count('A'), dna.count('T'), dna.count('G'), dna.count('C')]
    min_atgc = min(atgc)
    print(min_atgc)
    if atgc[0] == min_atgc:
        print('A'*N)
    elif atgc[1] == min_atgc:
        print('T'*N)
    elif atgc[2] == min_atgc:
        print('G'*N)
    else:
        print('C'*N)
728x90

'Python > 백준 문제 풀이' 카테고리의 다른 글

[BOJ] 9549번 암호화된 비밀번호  (0) 2022.12.03
[BOJ] 10252번 그리드 그래프  (0) 2022.11.13
[BOJ] 2448번 별 찍기 - 11  (0) 2022.10.25
[BOJ] 15828번 Router  (0) 2022.10.23
[BOJ] 2981번 검문  (1) 2022.10.08

댓글