πŸ‘©β€πŸŽ“κ³΅λΆ€ - 2024.02.01 μ†Œλ§ˆλŒ€λΉ„ λ¬Έμ œν’€μ΄

유령개·2024λ…„ 2μ›” 1일
0

PS-μ•Œκ³ λ¦¬μ¦˜2

λͺ©λ‘ 보기
24/34
post-thumbnail

10844 - μ‰¬μš΄ 계단 수

μ‰½μ§€μ•Šμ€ λ¬Έμ œμ˜€μŠ΅λ‹ˆλ‹€.

일단 μœ„μ™€κ°™μ΄ 각 자릿수의 차이가 1인 수λ₯Ό κ²Œλ‹¨μˆ˜λΌκ³  ν•  λ•Œ, μžλ¦Ώμˆ˜κ°€ 주어지면 ν•΄λ‹Ή μžλ¦Ώμˆ˜μ—μ„œ κ°€λŠ₯ν•œ 계단 수의 경우의 수의 합을 좜λ ₯ν•˜λ©΄ λ˜λŠ” λ¬Έμ œμž…λ‹ˆλ‹€.


뢄석

이 λ¬Έμ œκ°€ μ–΄λ €μš΄ μ΄μœ λ‘œλŠ” 두 가지가 μžˆμŠ΅λ‹ˆλ‹€.

일단 첫번째둜 κ·œμΉ™μ΄ κΉŒλ‹€λ‘œμ›Œμ„œ 점화식 μ„Έμš°λŠ” κ±° μžμ²΄κ°€ 쉽지 μ•Šλ‹€λŠ” κ±°κ³ , 두 번째둜 점화식을 두 경우둜 λ‚˜λˆ„μ–΄μ„œ 생각해봐야 ν•œλ‹€λŠ” μ μž…λ‹ˆλ‹€.

일단 첫번째 κ²½μš°λŠ” μœ„μ™€ 같이 N으둜 μ‹œμž‘ν•˜λŠ” 계단 수의 경우의 수λ₯Ό λ‚˜μ—΄ν•΄λ΄€μ„ λ•Œ μ²˜μŒμ— 보고 μ–΄? 이거

dp[i][j] = dp[i-1][j] + dp[i-1][j+1]인가? λ˜λŠ”
dp[i][j] = dp[i-1][j-1] + dp[i-1][j]인가 μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€.

ν•œλ§ˆλ””λ‘œ ν˜„μž¬ 쑰사쀑인 κ²½μš°λŠ” 이전 자릿수의 인덱슀 -1μ΄κ±°λ‚˜ +1이라고 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ 두 경우 λ‹€ μ˜€λ‹΅μ΄ λ‚˜μ˜΅λ‹ˆλ‹€.

ν•΄λ‹Ή λ¬Έμ œλŠ” 그림의 ν•˜λŠ˜/초둝 ν˜•κ΄‘νŽœμ²˜λŸΌ 점화식을 dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1] μ΄λΌλŠ” μœ„ μƒλŒ€κ°μ„  ν˜•νƒœλ‘œ μ°Ύμ•„μ•Ό 풀이가 κ°€λŠ₯ν•©λ‹ˆλ‹€. λ§λΆ™μ—¬μ„œ μƒλŒ€κ°μ„  ν˜•νƒœμ—¬μ•Όμ§€λ§Œ 0번 인덱슀λ₯Ό 쑰사할 λ•Œ (파이썬의 κ²½μš°μž…λ‹ˆλ‹€) -1κ³Ό 1을 μ°Έμ‘°ν•˜μ—¬ μ ν™”μ‹μœΌλ‘œ 0번째 인덱슀λ₯Ό μ •μƒμ μœΌλ‘œ μ°Έμ‘°ν•˜λŠ”κ²Œ κ°€λŠ₯ν•©λ‹ˆλ‹€.

두 번째 κ²½μš°λŠ” 9둜 μ‹œμž‘ν•˜λŠ” 계단 수의 κ²½μš°μž…λ‹ˆλ‹€.
계단 μˆ˜κ°€ 9둜 μ‹œμž‘ν•˜κ²Œ 되면 λ‹€λ₯Έ 점화식이 μ μš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μ²˜μŒμ—λŠ” dp[i][j-1]을 μ°Έμ‘°ν•˜λ©΄ ν•΄κ²°λ κΉŒ μ‹Άμ—ˆλŠ”λ° μ—­μ‹œ μ•„λ‹ˆμ—ˆμŠ΅λ‹ˆλ‹€. 이 κ²½μš°μ—λŠ” 그림의 λ…Έλž€ ν˜•κ΄‘νŽœμ²˜λŸΌ 상 μ’ŒλŒ€κ°μ„ μ˜ 수λ₯Ό κ°€μ Έλ‹€ 써야 정상적인 점화식이 κ°€λŠ₯ν•©λ‹ˆλ‹€.


μ½”λ”©

N = int(input())
dp = [[0]*9 for _ in range(N)]
for first in range(9):
    dp[0][first] = 1

dp배열을 λ§Œλ“€μ–΄μ£Όκ³  첫번째 λ¦¬μŠ€νŠΈλŠ” λ‹€ 1둜 μ΄ˆκΈ°ν™”ν•΄μ£Όκ² μŠ΅λ‹ˆλ‹€.

for i in range(1,N):
    for j in range(9):

2번째 λ¦¬μŠ€νŠΈλΆ€ν„° 1~NκΉŒμ§€μ˜ μžλ¦Ώμˆ˜λ§ˆλ‹€ 0~8둜 μ‹œμž‘ν•˜λŠ” 계단 수의 경우λ₯Ό λŒ€μž…ν•˜κ² μŠ΅λ‹ˆλ‹€.

        if j==8:
            dp[i][j] = dp[i-1][j-1]

μœ„μ— λΆ„μ„ν•œλŒ€λ‘œ ν˜„μž¬ 9둜 μ‹œμž‘ν•˜λŠ” 계단 수의 경우의 수λ₯Ό λŒ€μž…ν•΄μ£Όλ €λ©΄ 상 μ’ŒλŒ€κ°μ„ μ˜ 숫자λ₯Ό κΈ°μž…ν•΄μ€μ‹œλ‹€.

        else:
            dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1]

κ·Έ κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄ 상 μ’Œμš°λŒ€κ°μ„ μ˜ 수λ₯Ό ν•˜λ‚˜μ”© 뽑아 λ”ν•œ 값을 ν˜„μž¬ 계단 수의 경우의 μˆ˜μ— λ„£μ–΄μ£Όλ©΄ λ©λ‹ˆλ‹€.

print(sum(dp[N-1])%1000000000)

λ§ˆμ§€λ§‰μœΌλ‘œ 문제 μ‘°κ±΄λŒ€λ‘œ ν•΄λ‹Ή 자릿수의 계단 수의 합산에 10얡을 λ‚˜λˆˆ λ‚˜λ¨Έμ§€λ₯Ό 좜λ ₯ν•˜λ©΄ λ©λ‹ˆλ‹€.




1932번 - μ •μˆ˜ μ‚Όκ°ν˜•

μ•„λž˜λ‘œ λ‚΄λ €μ˜€λ©΄μ„œ λŒ€κ°μ„ μœΌλ‘œ 값을 ν•©μ‚°ν•  수 μžˆλŠ”λ° μ΅œμ’…μ μœΌλ‘œ 내렀왔을 λ•Œ κ°€μž₯ 큰 값이 λ˜λŠ” 수λ₯Ό κ΅¬ν•˜λ©΄ λ˜λŠ” λ¬Έμ œμž…λ‹ˆλ‹€.

import copy
N = int(input())
lst = []
for _ in range(N):
    lst.append(list(map(int,input().split())))
dp = copy.deepcopy(lst)

일단 μ € μ •μˆ˜μ‚Όκ°ν˜•μ„ 리슀트둜써 λ°›κ³  DP 기둝을 ν•˜κΈ° μœ„ν•΄ 리슀트λ₯Ό deepcopy ν•΄μ£Όκ² μŠ΅λ‹ˆλ‹€.

for i in range(len(dp)-1):
    for j in range(len(dp[i])):

그리고 μœ„μ—μ„œλΆ€ν„° 끝-1 κΉŒμ§€ 합산을 μœ„ν•΄ 리슀트λ₯Ό μˆœνšŒν•˜κ² μŠ΅λ‹ˆλ‹€.

        if lst[i+1][j] + dp[i][j] > dp[i+1][j]:
            dp[i+1][j] = lst[i+1][j] + dp[i][j]

첫 번째 κ²½μš°λΆ€ν„° μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.
ν˜„μž¬ DPμ—λŠ” λ‚˜μ˜¬ 수 μžˆλŠ” μ΅œλŒ€κ°’μ΄ κΈ°λ‘λ˜μ–΄μžˆλ‹€κ³  κ°€μ •ν•΄μ•Όν•©λ‹ˆλ‹€.

λ°”λ‘œ μ•„λž˜ μžˆλŠ” κ°’ + ν˜„μž¬κΉŒμ§€ 기둝된 μ΅œλŒ€κ°’ 이 λ°”λ‘œ μ•„λž˜ 기둝될 μ΅œλŒ“κ°’λ³΄λ‹€ 크닀면
λ°”λ‘œ μ•„λž˜ 기둝될 μ΅œλŒ“κ°’ = λ°”λ‘œ μ•„λž˜ μžˆλŠ” κ°’ + ν˜„μž¬κΉŒμ§€ 기둝된 μ΅œλŒ€κ°’μœΌλ‘œ ν‘œκΈ°ν•΄μ€μ‹œλ‹€.

        if lst[i+1][j+1] + dp[i][j] > dp[i+1][j+1]:
            dp[i+1][j+1] = lst[i+1][j+1] + dp[i][j]

ν”ΌλΌλ―Έλ“œλŠ” μ–‘ λŒ€κ°μ„  λ°©ν–₯μ΄λ―€λ‘œ 였λ₯Έμͺ½μ— μžˆλŠ” 인덱슀 ν•˜λ‚˜ 더 μ½”λ”©ν•΄μ£Όμ‹œλ©΄ λ©λ‹ˆλ‹€.

print(max(dp[-1]))

λ§ˆμ§€λ§‰μœΌλ‘œ κ°€μž₯ μ•„λž« κ°’μ—μ„œ κ°€μž₯ 큰 값이 λ‚˜μ˜¬ 수 μžˆλŠ” μ΅œλŒ€ 경우의 μˆ˜μ΄λ―€λ‘œ 좜λ ₯ν•˜μ‹œλ©΄ λ©λ‹ˆλ‹€.




profile
ν•œλ¦ΌλŒ€ν•™κ΅ μ •λ³΄κ³Όν•™λŒ€ 2ν•™λ…„ μž¬ν•™μ€‘ / 윑ꡰ μ •λ³΄λ³΄ν˜Έλ³‘ 22-2κΈ°

0개의 λŒ“κΈ€