πŸ‘©β€πŸŽ“κ³΅λΆ€ - 2024.01.23 였늘의 코딩곡뢀

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

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

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

κ·Έλ™μ•ˆ BFS와 DFS κ³¨λ“œ λ¬Έμ œλ“€μ„ ν’€μ–΄λ³΄λ©΄μ„œ μ•Œκ³ λ¦¬μ¦˜μ΄ μ–΄λ–€ 건지, μ–΄λ–»κ²Œ ν™œμš©ν•˜μ—¬ ν•΄κ²° ν•  수 μžˆλŠ”μ§€ 감을 μž‘μ•„κ°”μŠ΅λ‹ˆλ‹€.

μ•½ 47일간 DFS와 BFSλ₯Ό ν•΄κ²°ν–ˆμœΌλ―€λ‘œ ν•˜λ‚˜λ§Œ κ³„μ†ν•΄μ„œ νž˜λ“  것도 있고 보닀 λ‹€μ–‘ν•œ μ•Œκ³ λ¦¬μ¦˜μ„ μ ‘ν•˜κ³ μž μ˜€λŠ˜λΆ€ν„°λŠ” DP μ•Œκ³ λ¦¬μ¦˜μ— μ†λŒ€λ³΄λ €κ³  ν•©λ‹ˆλ‹€.


DPλž€?

Dynamic Programming의 μ•½μžμž…λ‹ˆλ‹€.

def dp(N):
    if(N==1): return 1
    if(N==2): return 1
    return dp(N-1) + dp(N-2)
print(dp(10))

μ—¬κΈ° ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄μ„ κ΅¬ν•˜λŠ” 식이 μžˆμŠ΅λ‹ˆλ‹€.
μ΄λ ‡κ²Œ 코딩을 μž‘μ„±ν•˜κ³  싀행해보면

μ΄λŸ¬ν•œ ν˜•μ‹μ„ 거쳐 μž¬κ·€μ μœΌλ‘œ μ‹€ν–‰λ˜κ² μ£ .
그런데 μœ„ μ‹€ν–‰ ν˜•μ‹μ„ μžμ„Ένžˆ 듀여닀보면

dp(8)도 λ‘λ²ˆ 쓰이고

dp(7)도 λ‘λ²ˆ μ“°μ΄λ‹ˆ 효율이 ꡉμž₯히 λ–¨μ–΄μ§„λ‹€λŠ” 생각이 듀지 μ•Šλ‚˜μš”?
μ‹€μ œλ‘œ μ»΄ν“¨ν„°μ—μ„œ μœ„ μ½”λ“œ μ»΄νŒŒμΌμ„ 돌렀보면

dp(10)같은 κ²½μš°λŠ” 55둜 잘 λ‚˜μ˜€λŠ”λ°


dp(50)같은 κ²½μš°λŠ” λ•Œλ €μ£½μ—¬λ„ μ•ˆλ‚˜μ˜΅λ‹ˆλ‹€.

근데 이건 λ‹Ήμ—°ν•œ ν˜„μƒμž…λ‹ˆλ‹€. μœ„ μ½”λ“œλŒ€λ‘œ dp(50)을 ꡬ할 κ²½μš°μ—” 1,000,000 초 = μ•½ 277μ‹œκ°„ ν›„μ—λ‚˜ 컴파일 값이 λ‚˜μ˜¬ κ²λ‹ˆλ‹€.

μ΄λ ‡κ²Œ μ“Έλͺ¨μ—†λŠ” 더미 μžλ£Œλ“€(μœ„ μ˜ˆμ‹œμ—μ„œμ˜ dp(8),dp(7) λ“±)을 쀄이고 μ‹œκ°„λ³΅μž‘λ„λ₯Ό 2의 nμŠΉμ—μ„œ O(n)으둜 획기적이게 쀄일 수 μžˆλŠ” μ•Œκ³ λ¦¬μ¦˜μ΄ λ°”λ‘œ DP의 λ©”λͺ¨μ΄μ œμ΄μ…˜μž…λ‹ˆλ‹€.

μ‰½κ²Œ μ„€λͺ…ν•˜λ©΄ μ € 더미 μžλ£Œλ“€μ„ λ°°μ—΄ ν•˜λ‚˜ λ§Œλ“€μ–΄μ„œ μ €μž₯ν•˜κ³ , λ§Œμ•½μ— ν˜„μž¬ 쑰사쀑인 N이 λ°°μ—΄ μ•ˆμ— μžˆλŠ” 자료라면 κ·ΈλŒ€λ‘œ κ°–λ‹€ μ¨λ¨ΉλŠ” λ°©μ‹μž…λ‹ˆλ‹€.

memo = [0] * 100
def dp(N):
    if(N==1): return 1
    if(N==2): return 1
    if(memo[N] != 0): return memo[N]
    memo[N] = dp(N-1) + dp(N-2)
    return memo[N]
print(dp(55))

이런 λ°©μ‹μœΌλ‘œ λ°°μ—΄ ν•˜λ‚˜ λ§Œλ“€μ–΄μ£Όκ³  λ©”λͺ¨κ°€ λΉ„μ–΄μžˆμ§€ μ•ŠμœΌλ©΄ ν•΄λ‹Ή λ©”λͺ¨λ‘œ return ν•΄μ€λ‹ˆλ‹€.
그리고 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•  λ•Œλ§ˆλ‹€ memo의 n번째
μΈλ±μŠ€μ— ν•΄λ‹Ήν•˜λŠ” 값을 λ„£μ–΄μ€λ‹ˆλ‹€.
μœ„ 식을 μ‹€ν–‰ν•˜λ©΄

μ΄λŸ°μ”©μœΌλ‘œ μ‹œκ°„λ³΅μž‘λ„κ°€ 크게 쀄어 금방 컴파일 값을 λ„μΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€.


1003번 - ν”Όλ³΄λ‚˜μΉ˜ ν•¨μˆ˜

본격적으둜 λ¬Έμ œν’€μ΄λ₯Ό ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.
ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄μ—μ„œ N을 ν˜ΈμΆœν•  λ•Œ 0κ³Ό 1이 각각 λͺ‡λ²ˆ λΆˆλŸ¬μ™€μ§€λŠ”μ§€ 횟수λ₯Ό κ΅¬ν•˜λžλ‹ˆλ‹€.

T = int(input())
for _ in range(T):
    zero = 0
    one = 0
    memo = [0]*41
    a = int(input())
    fib(a)

λ¨Όμ € 선언을 ν•΄μ£Όκ³  λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ μœ„ν•œ memo의 κΈΈμ΄λŠ” n<41μ΄λ―€λ‘œ 41둜 μ„€μ •ν•˜κ² μŠ΅λ‹ˆλ‹€.

    if a == 0:
        print(1,0)
    elif a == 1:
        print(0,1)
    elif a == 2:
        print(1,1)
    else:
        print(memo[a-1],memo[a])

DPλŠ” 점화식을 μ„Έμ›Œμ£ΌλŠ”κ²Œ 제일 μ€‘μš”ν•œλ° μœ„μ™€ 같은 μ˜ˆμ™Έμ˜ κ²½μš°κ°€ μ•„λ‹ˆλ©΄ 1κ³Ό 0의 호좜횟수λ₯Ό λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ 톡해 μ•Œμ•„λ‚Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

def fib(N):
    if (N == 0): 
        return 0
    if (N == 1):
        return 1
    if (memo[N] != 0):
        return memo[N]
    memo[N] = fib(N-1) + fib(N-2)
    return memo[N]

λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ μ‚¬μš©ν•˜μ—¬ λ©”λͺ¨μ— λ‹΄κ²¨μžˆμœΌλ©΄ return memo[N] ν˜•μ‹μœΌλ‘œ return ν•΄μ£Όκ³  λ©”λͺ¨μ— λ‹΄κ²¨μžˆμ§€ μ•Šλ‹€λ©΄ memo[n]을 fib(n-1) + fib(n-2)둜 μ§€μ •ν•΄μ€μ‹œλ‹€.



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

0개의 λŒ“κΈ€