본문 바로가기

알고리즘/소프티어

[파이썬] Softeer 연습문제 #3. 징검다리 (Lv. 3) 완벽해설

250

문제

 

https://softeer.ai/practice/6293

 

Softeer - 현대자동차그룹 SW인재확보플랫폼

남북으로 흐르는 개울에 동서로 징검다리가 놓여져 있다. 이 징검다리의 돌은 들쑥날쑥하여 높이가 모두 다르다. 철수는 개울의 서쪽에서 동쪽으로 높이가 점점 높은 돌을 밟으면서 개울을 지

softeer.ai

 

 

해설

 

https://vehiclewithai.tistory.com/4

 

Softeer 연습문제 [파이썬] #1. A+B 해설

문제 제약조건 두 정수 A와 B는 1이상 9이하의 정수이다. 입력형식 첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. 출력형

vehiclewithai.tistory.com

(입력값을 받아들여 처리하는 부분은 위 홈페이지에 자세히 설명되어 있으니 참고바랍니다.)

 

(수정합니다)

이 문제를 풀기 위해서는 이전의 최댓값을 저장하는 기능이 필요하다.

이는 "투 포인터 알고리즘" 을 통해 구현할 수가 있다.

 

예제로 예를 들때, 

3, 2, 1, 4, 5 라는 5가지 숫자가 있을 때,

이 5가지의 숫자를 2개의 포인터가 돌아다니는 방식으로 구현할 수가 있다.

 

3이라는 숫자가 최대값일 때, 포인터1에 3이라는 숫자의 인덱스값을 저장해주고, 다른 하나의 포인터2는 계속해서 오른쪽으로 나가며 포인터1의 숫자와 비교를 해준다. 만약 포인터2가 가리키는 숫자가 포인터1의 숫자보다 크다면 포인터1의 인덱스는 포인터2가 가르키는 인덱스로 갱신됨과 동시에 "1"이 더해져 밟을 수 있는 돌의 갯수를 계속해서 더하는 방식으로 진행할 수가 있다.

 

처음에 문제를 잘못 이해해서 투포인터를 사용하는 문제로 이해를 해버렸다. 알고보니 동적프로그래밍을 사용해서 푸는 문제였다.

 

1. 즉 현재의 돌의 높이와 이전에 밟아야 할 돌들의 높이를 비교하고,

2. 만약 이전의 돌의 높이가 현재의 돌보다 낮다면 (그럼 건널 수 있다는 의미니깐)

3. "이전의 돌에서의 스텝수+1"와 "현재의 돌의 스텝수" 중 최대값으로 "현재의 스텝수"를 갱신해준다. 

4. 그렇게 i가 끝에 도달했을 무렵에는 각각의 돌에서 시작했을 경우의 최대 스텝수가 리스트에 담기게 되는데,

5. 그 최대 스텝수의 리스트의 최대값을 출력해주면 결국 밟을 수 있는 돌의 최대 갯수가 된다.

 

이를 코드로 작성하면 아래와 같다. 

 

 

코드

 

import sys

# 입력값 받아들이기
N = int(sys.stdin.readline()) # 돌의 갯수
stones = list(map(int, sys.stdin.readline().split())) # 돌의 높이로 이루어진 리스트
dyn = [1]*N # 동적프로그래밍을 위한 테이블 준비

# 현재의 돌 i
for i in range(1,N):
  # i 이전의 돌을 밟는 경우를 시뮬레이션 돌려보는데,
  for j in range(i):
    # 만약 현재의 돌의 높이가 시뮬레이션에서의 돌의 높이보다 높을 경우
    if (stones[i] > stones[j]): 
      # "현재의 돌의 스텝수"와 "이전의 돌들을 밟고 현재의 돌을 밟을 경우의 스텝수 + 1" 중 최대값으로 갱신해준다.
      dyn[i] = max(dyn[i], dyn[j]+1) 
        
# 밟을 수 있는 돌의 갯수 출력
print(max(dyn))

 

 

결과