문제
https://www.acmicpc.net/problem/12026
BOJ 거리는 보도블록 N개가 일렬로 놓여진 형태의 도로이다. 도로의 보도블록은 1번부터 N번까지 번호가 매겨져 있다.
스타트의 집은 1번에 있고, 링크의 집은 N번에 있다. 스타트는 링크를 만나기 위해서 점프해가려고 한다.
BOJ거리의 각 보도블록에는 B, O, J 중에 하나가 쓰여 있다. 1번은 반드시 B이다.
스타트는 점프를 통해서 다른 보도블록으로 이동할 수 있다. 이때, 항상 번호가 증가하는 방향으로 점프를 해야 한다. 만약, 스타트가 현재 있는 곳이 i번이라면, i+1번부터 N번까지로 점프를 할 수 있다. 한 번 k칸 만큼 점프를 하는데 필요한 에너지의 양은 k*k이다.
스타트는 BOJ를 외치면서 링크를 만나러 가려고 한다. 따라서, 스타트는 B, O, J, B, O, J, B, O, J, ... 순서로 보도블록을 밟으면서 점프를 할 것이다.
스타트가 링크를 만나는데 필요한 에너지 양의 최솟값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 1 ≤ N ≤ 1,000이 주어진다.
둘째 줄에는 보도블록에 쓰여 있는 글자가 1번부터 순서대로 주어진다.
출력
스타트가 링크를 만나는데 필요한 에너지 양의 최솟값을 출력한다. 만약, 스타트가 링크를 만날 수 없는 경우에는 -1을 출력한다.
풀이
처음 머리가 어지러울 때 풀다가 잘 안돼서 다른 날에 다시 풀어봤다.
맨 처음에는 nXn 배열을 만들어서 각 문자별로 다음 문자까지의 비용을 저장해 두려 했는데
최종 비용의 최솟값을 찾는 데 n^2 초과 시간이 걸릴 것 같아 포기했다.
다른 날 다시 보니 굳이 그렇게 할 필요 없이
for문을 두 번 돌며 기준 이전의 블록까지의 비용 + 그 블록으로부터 기준 블록까지의 비용 중 작은 값을 선택하면 됐다.
자세한 설명은 코드에 주석으로 달아놓았다.
n = int(input())
blocks = list(input())
pre = {'B': 'J', 'O': 'B', 'J': 'O'} #각 문자의 이전 문자 저장, 이전에 올 수 있는 블록을 찾아야 하기 때문
dp = [0] + [10000001]*n #처음 'B'블록 제외 최댓값으로 설정
for i in range(1, n): #기준이 되는 블록
p = pre[blocks[i]] #기준 블록에 도달할 수 있는 문자 ex) 'B' -> 'J', 'O' -> 'B'
for j in range(i): #기준 이전까지의 블록 탐색
if blocks[j] == p:
dp[i] = min(dp[i], dp[j] + (i-j)**2) #기준 블록까지의 비용 중 작은 값 저장
if dp[n-1] == 10000001:
print(-1)
else:
print(dp[n-1])
'알고리즘 스터디' 카테고리의 다른 글
[백준] 2281 데스노트 - 파이썬 (0) | 2022.02.11 |
---|---|
[백준] 5557 1학년 - 파이썬 (0) | 2022.02.08 |
[백준] 11058 크리보드 파이썬 (0) | 2022.02.02 |
[백준] 1495 기타리스트 - 파이썬 (0) | 2022.02.02 |
[백준] 15989 1,2,3 더하기 4 파이썬 (0) | 2022.01.23 |