백준 - 단어섞기 9177 (DP, 그래프)

Chan Young Jeong·2024년 2월 17일
0

알고리즘

목록 보기
25/27

단어 섞기

처음 봤을 때는 정확한 문제의 유형이 떠오르지 않았다. 그래서 이럴 때는 예시를 통해서 문제 풀이 방식을 생각해본다. 일단 주어진 예시에서 CAT TREE CATRTEE 였을 때를 생각해봤다.
과정을 생가해보면 완전 탐색으로 문제를 풀어야 할 것 같았다. CAT, TREE에서 현재 어디 위치를 가리키고 있는 포인터를 i,j 라고 하면 i,j를 움직이면서 CATRTEE를 만들어야 한다.
그래서 맨 처음에는 아무 위치를 가리키고 있지 않으니 0,0이고 i=1, j=0이라는 건 CAT에서 첫 번째 위치인 C를 가리키고 있고 CATRTEE에서 C까지 만들었다는 것을 의미한다. 이렇게 각 스탭에서 i를 움직일 것인지, j를 움직인 것인지를 판단하면 된다. 그런데 여기서 잘 생각해보면 완전 탐색을 하면서 i, j 의 값이 겹치는 경우들이 발생한다. 따라서 여기서 겹치는 부분 문제가 발생을 하기 때문에, 이 부분을 기록했다가 판단을 하면 모든 경우의 수를 탐색하지 않고 문제를 풀 수 있다. 따라서 dp 를 적용해서 문제를 풀 수 있다.

DP[i][j]를 첫 번째 단어에서 i 번째까지 사용이 되었고, 두 번째 단어에서 j 번째까지 사용되었을 때 타겟 문자를 만들 수 있는 지 없는 지로 정의했다.

import sys

dp = None
def solve(first, second, target, x, y):

    if x + y == len(first) + len(second):
        return True

    if not dp[x][y]:
        return dp[x][y]

    a = False
    b = False
    
    next_x = x + 1
    if next_x <= len(first) and first[next_x - 1] == target[next_x + y - 1]:
        a = solve(first, second, target, next_x, y)

    next_y = y + 1
    if next_y <= len(second) and second[next_y - 1] == target[x + next_y - 1]:
        b = solve(first, second, target, x, next_y)

    dp[x][y] = a | b

    return dp[x][y]


n = int(sys.stdin.readline())
for i in range(n):
    words = sys.stdin.readline().strip().split(' ')
    dp = [[True for _ in range(len(words[1])+1)]for _ in range(len(words[1])+1)]
    if (solve(words[0], words[1], words[2],0,0)) :
        print(f'Data set {i+1}: yes')
    else:
        print(f'Data set {i+1}: no')

0개의 댓글