danuri
오늘의 기록
danuri
전체 방문자
오늘
어제
  • 오늘의 기록 (307)
    • java (150)
      • java (33)
      • spring (63)
      • jpa (36)
      • querydsl (7)
      • intelliJ (9)
    • kotlin (8)
    • python (24)
      • python (10)
      • data analysis (13)
      • crawling (1)
    • ddd (2)
    • chatgpt (2)
    • algorithm (33)
      • theory (9)
      • problems (23)
    • http (8)
    • git (8)
    • database (5)
    • aws (12)
    • devops (10)
      • docker (6)
      • cicd (4)
    • book (44)
      • clean code (9)
      • 도메인 주도 개발 시작하기 (10)
      • 자바 최적화 (11)
      • 마이크로서비스 패턴 (0)
      • 스프링으로 시작하는 리액티브 프로그래밍 (14)
    • tistory (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

태그

  • DDD
  • Security
  • Kotlin
  • ChatGPT
  • docker
  • mockito
  • 자바 최적화
  • RDS
  • S3
  • Saving Plans
  • Database
  • 도메인 주도 설계
  • JPA
  • CICD
  • PostgreSQL
  • Java
  • 등가속도 운동
  • Jackson
  • AWS
  • 마이크로서비스패턴
  • POSTGIS
  • connection
  • 트랜잭션
  • Spring
  • nuribank
  • gitlab
  • reactive
  • Bitmask
  • Thymeleaf
  • SWAGGER

최근 댓글

최근 글

hELLO · Designed By 정상우.
danuri

오늘의 기록

algorithm/problems

금광

2021. 2. 4. 01:49

문제

N*M 크기의 금광이 있다. 금광은 1*1 크기의 칸으로 나누어져 있다.
채굴자는 첫 번째 열, 어느 행에서 출발하여 금을 캐기 시작한다.
이후에 m번에 걸쳐 오른쪽 위, 오른쪽, 오른쪽 아래 3가지 중 하나의 위치로 이동한다.
결과적으로 채굴자가 얻을 수 있는 금의 최대 크기를 구한다.

 

 

입력

첫째 줄에 테스트 케이스 T (1 ~ 1000)
매 테스트 케이스 첫째 줄에 n, m (1 ~ 20)
둘째 줄에 n*m개의 위치에 매장된 금의 개수 (1 ~ 100)

 

출력

매 테스트 케이스마다 채굴자가 얻을 수 있는 금의 최대 크기를 출력한다.

 

 

풀이

# 테스트 케이스(Test Case) 입력
for tc in range(int(input())):
    # 금광 정보 입력
    n, m = map(int, input().split())
    array = list(map(int, input().split()))

    # 다이나믹 프로그래밍을 위한 2차원 DP 테이블 초기화
    dp = []
    index = 0
    for i in range(n):
        dp.append(array[index:index + m])
        index += m

    # 다이나믹 프로그래밍 진행
    for j in range(1, m):
        for i in range(n):
            # 왼쪽 위에서 오는 경우
            if i == 0:
                left_up = 0
            else:
                left_up = dp[i - 1][j - 1]
            # 왼쪽 아래에서 오는 경우
            if i == n - 1:
                left_down = 0
            else:
                left_down = dp[i + 1][j - 1]
            # 왼쪽에서 오는 경우
            left = dp[i][j - 1]
            dp[i][j] = dp[i][j] + max(left_up, left_down, left)

    result = 0
    for i in range(n):
        result = max(result, dp[i][m - 1])

    print(result)

2차원 dp 테이블을 이용한 다이나믹 프로그래밍으로 풀 수 있다. 금광의 모든 위치에 대해

  1. 왼쪽 위에서 오는 경우
  2. 왼쪽 아래에서 오는 경우
  3. 왼쪽에서 오는 경우

3가지 경우만 존재한다. 따라서 이 3가지 경우 중에서 가장 많은 금을 가지고 있는 경우를 테이블에 저장해준다.

 

점화식은 다음과 같다.

dp[i][j] = array[i][j] + max(dp[i-1][j-1], dp[i][j-1], dp[i+1][j-1])

'algorithm > problems' 카테고리의 다른 글

못생긴 수  (0) 2021.02.04
백준 18353 - 병사 배치하기  (0) 2021.02.04
프로그래머스 - 가사 검색  (0) 2021.01.27
백준 2110 - 공유기 설치  (0) 2021.01.26
백준 1715 - 카드 정렬하기  (0) 2021.01.21
    'algorithm/problems' 카테고리의 다른 글
    • 못생긴 수
    • 백준 18353 - 병사 배치하기
    • 프로그래머스 - 가사 검색
    • 백준 2110 - 공유기 설치
    danuri
    danuri
    IT 관련 정보(컴퓨터 지식, 개발)를 꾸준히 기록하는 블로그입니다.

    티스토리툴바