μ•Œκ³ λ¦¬μ¦˜ 곡뢀 기둝

[μ΄μ½”ν…Œ/python] λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ° κ°œλ… 정리 & 문제 풀이 기둝 βž• λ°±μ€€ dp 문제 풀이

hyeonha 2024. 5. 29. 15:08

DP

 

DPλŠ” ν•œλ²ˆ ν•΄κ²°ν•œ λ¬Έμ œλŠ” λ‹€μ‹œ κ³„μ‚°ν•˜μ§€ μ•Šλ„λ‘ ν•œλ‹€.

 

λ©”λͺ¨λ¦¬ 곡간이 ν•„μš”ν•  λ•Œλ§ˆλ‹€ ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λ˜λŠ” 도쀑에 ν•„μš”ν•œ λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•˜λŠ” 것이 μžλ£Œκ΅¬μ‘°μ—μ„œμ˜ λ‹€μ΄λ‚˜λ―Ήμ˜ 의미!

 

ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄

λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°μœΌλ‘œ ν•΄κ²°ν•  수 μžˆλŠ” λŒ€ν‘œμ μΈ 문제

 

점화식은 μž¬κ·€ν•¨μˆ˜ν˜•νƒœλ‘œ κ΅¬ν˜„ κ°€λŠ₯

μ•ž λ‘κ°œμ˜ 항을 λ”ν•˜μ—¬ κ·Έ λ‹€μŒ 항을 λ§Œλ“ λ‹€.

f(3)을 ν˜ΈμΆœν•  λ•Œ f(2)와 f(1)을 ν˜ΈμΆœν•œ κ²°κ³Όλ₯Ό λ”ν•΄μ„œ  ꡬ할 수 μžˆλ‹€.

def fibo(x):
  if x==1 or x ==2:
    return 1
  return fibo(x-1) + fibo(x-2)

print(fibo(4))


# μž¬κ·€ν•¨μˆ˜λ₯Ό λ§Œλ“€ λ•Œν•΄λŠ” λ¬΄ν•œ λ°˜λ³΅ν•˜μ§€ μ•Šλ„λ‘ μ’…λ£Œμ‘°κ±΄μ„ μ μ–΄μ€˜μ•Όν•œλ‹€! 
# x κ°€ 1 λ˜λŠ” 2일 λ•Œκ°€ μ’…λ£Œ 쑰건이닀.

점화식 뢀뢄이 μž¬κ·€μ‹, a1κ³Ό a2이 μ’…λ£Œμ‘°κ±΄μ΄ λœλ‹€.

 

 

f(6)을 ν˜ΈμΆœν–ˆμ„ 뿐인데 f(2)κ°€ 5번 호좜되고 μžˆλ‹€. -> μˆ˜ν–‰ μ‹œκ°„ λΉ„νš¨μœ¨ 

λ”°λΌμ„œ ν•œλ²ˆ ν•΄κ²°ν•œ f(2)에 λŒ€ν•΄μ„œ 이 문제의 닡은 이거라고 μ•Œλ €μ€„ 수 μžˆλ„λ‘ ν•΄μ•Ό ν•œλ‹€

 

.

 

λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ° 문제 ν•΄κ²° 방법 (ν•˜ν–₯식)

λ°°μ—΄ 이름을 cache, table ,dp, d라고 μ„€μ •ν•˜κ³€ ν•œλ‹€.

상ν–₯식은 λ°˜λ³΅λ¬Έμ„ ν•΄κ²°ν•œλ‹€. 

dpλ₯Ό ν•΄κ²°ν•˜λŠ” 방법 쀑 ν•˜ν–₯μ‹μœΌλ‘œ μ ‘κ·Όν•  λ•Œ λ©”λͺ¨μ΄μ œμ΄μ…˜ 방법을 μ‚¬μš©ν•  수 μžˆλ‹€.

 

ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄ νƒ‘λ‹€μš΄ λ©”λͺ¨μ΄μ œμ΄μ…˜ 방식 κ΅¬ν˜„ 

#ν•œλ²ˆ κ³„μ‚°λœ κ²°κ³Όλ₯Ό λ©”λͺ¨μ΄μ œμ΄μ…˜ν•˜κΈ° μœ„ν•œ 리슀트 μ΄ˆκΈ°ν™”
d = [0] * 100

# ν”Όλ³΄λ‚˜μΉ˜ ν•¨μˆ˜λ₯Ό μž¬κ·€ν•¨μˆ˜λ‘œ κ΅¬ν˜„ (νƒ‘λ‹€μš΄ λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°)

def fibo(x):

  # μ’…λ£Œ 쑰건 (1 λ˜λŠ” 2일 λ•Œ 1 λ°˜ν™˜)
  if x==1 or x==2:
    return 1
  
  # 이미 κ³„μ‚°ν•œμ  μžˆλŠ” 문제면 κ·ΈλŒ€λ‘œ λ°˜ν™˜
  if d[x] != 0:
    return d[x]
  
  # 아직 κ³„μ‚°ν•˜μ§€ μ•Šμ€ 문제라면 점화식에 따라 ν”Όλ³΄λ‚˜μΉ˜ κ²°κ³Ό λ°˜ν™˜
  d[x] = fibo(x-1) + fibo(x-2)
  return d[x]
print(fibo(99))

 

ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄ λ°”ν…€μ—… 방식 κ΅¬ν˜„

# μ•žμ„œ κ³„μ‚°λœ κ²°κ³Όλ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•œ dp ν…Œμ΄λΈ” μ΄ˆκΈ°ν™”
d = [0] * 100

# 첫번째, λ‘λ²ˆμ§Έ ν”Όλ³΄λ‚˜μΉ˜ μˆ˜λŠ” 1
d[1] = 1
d[2] = 1
n=99

# λ°”ν…€μ—… 방식은 μž¬κ·€κ°€ μ•„λ‹Œ 반볡문으둜 κ΅¬ν˜„!
# μž‘μ€ λ¬Έμ œλΆ€ν„° ν•΄κ²°ν•˜κ³ , λ¨Όμ € 해결해놓은 문제λ₯Ό μ‘°ν•©ν•΄μ„œ μ•žμœΌλ‘œμ˜ 큰 문제λ₯Ό μ°¨λ‘€λŒ€λ‘œ κ΅¬ν•œλ‹€.
for i in range(3,n+1):
  d[i] = d[i-1] + d[i-2]

print(d[n])

 


 

μ§€μˆ˜ μ‹œκ°„λ§ŒνΌ 걸리던 ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄ 문제의 μ‹œκ°„ λ³΅μž‘λ„λ₯Ό  O(N) 만큼 쀄일 수 μžˆλ‹€.


 

피벗을 5둜 μ„€μ • ν›„ 퀡 정렬을 μˆ˜ν–‰ν•˜λ©΄ 5보닀 μž‘μ€ μ›μ†Œμ™€ 5보닀 큰 μ›μ†Œλ‘œ λΆ„λ¦¬λœλ‹€.

μ΄λ ‡κ²Œ ν•œλ²ˆ 뢄할이 이루어진 이후 5에 λŒ€ν•΄μ„œλŠ” 이제 μ²˜λ¦¬λ˜μ§€ μ•ŠλŠ”λ‹€. λ‹€λ₯Έ λΆ€λΆ„ λ¬Έμ œμ— ν¬ν•¨λ˜μ§€ μ•ŠλŠ”λ‹€.


- μž‘μ€ 문제λ₯Ό 톡해 큰 문제λ₯Ό ν•΄κ²°

- λΆ€λΆ„ λ¬Έμ œκ°€ 쀑볡

 

-> λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°μœΌλ‘œ μ ‘κ·Ό


1️⃣싀전 문제 1  : 1둜 λ§Œλ“€κΈ°

 

μ—°μ‚°μ˜ μ΅œμ†Ÿκ°’μ„ κ΅¬ν•˜λŠ” λ¬Έμ œμ΄λ‹€.

λ‹¨μˆœνžˆ 5둜 λ‚˜λˆ„κΈ°, 3으둜 λ‚˜λˆ„κΈ°, 1을 λΉΌμ£ΌλŠ” 연산을 λ°˜λ³΅ν•˜λŠ” 것이 μ•„λ‹ˆλΌ μž…λ ₯된 값에 λ”°λΌμ„œ μž…λ ₯값을 1둜 λ§Œλ“œλŠ” μ—°μ‚°μ˜ μ΅œμ†Ÿκ°’μ„ κ΅¬ν•΄μ•Όν•˜λŠ” λ¬Έμ œμ˜€λ‹€.

 

λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°μ„ μ΄μš©ν•΄μ„œ 

μž…λ ₯값이 1일 λ•ŒλΆ€ν„° 

 

 

초기 μ½”λ“œλ‹€.. μ–΄λ–€ λ°©μ‹μœΌλ‘œ ν’€μ–΄μ•Όν• μ§€ 감이 잘 μž‘νžˆμ§€ μ•Šμ•˜λ‹€.

n = int(input().split())
count =0
def fibo(x):
  while(True):
    if x==1:
      return count 
    elif x % 5 ==0:
      count +=1
      x = x//5
    elif x % 3==0:
      count +=1
      x = x//3
    else:
      count +=1
      x -=1
  
fibo(n)

 

 

μ΅œμ’… μ½”λ“œλŠ” μ•„λž˜μ™€ κ°™λ‹€.

 

λ§Œμ•½ 2둜 λ‚˜λˆ„μ–΄ λ–¨μ–΄μ§€λŠ” 경우 1을 λΊ€ 경우의 μ—°μ‚° νšŸμˆ˜κ°€ μ €μž₯된 d[i]와 d[i//2] + 1을 λΉ„κ΅ν•˜μ—¬ 더 μž‘μ€ 방법을 μ„ νƒν•œλ‹€λŠ” 아이디어이닀.

 # 1을 λΊ€ 경우 μ—°μ‚° 횟수
 d[i] = d[i-1]  +1
 
 # 2둜 λ‚˜λˆ„μ–΄ λ–¨μ–΄μ§€λŠ” 경우
  if i%2 ==0:
    d[i] = min(d[i],d[i//2]+1)

 

 

전체 μ½”λ“œ

x = int(input())

d = [0] * 30001

for i in range(2,x+1):
 
  d[i] = d[i-1]  +1
  if i%2 ==0:
    d[i] = min(d[i],d[i//2]+1)

  if i%3==0:
    d[i] = min(d[i],d[i//3]+1)
  
  if i%5==0:
    d[i] = min(d[i],d[i//5]+1)
 
print(d[x])

2️⃣싀전 문제 2 :개미 전사 문제 풀이 κ³Όμ •

🐜🐜

 

아직 문제 풀이λ₯Ό μ–΄λ–»κ²Œ ν•΄μ•Όν• μ§€ λ°”λ‘œ λ– μ˜€λ₯΄μ§€ μ•ŠλŠ”λ‹€. 풀이λ₯Ό 보고 dp λ¬Έμ œμ— μ΅μˆ™ν•΄μ§€μž! 

n = int(input())

array = list(map(int,input().split()))

d =[0] * 100 


d[0] = array[0]
d[1] = max(array[0],array[1])


for i in range(2,n):
  d[i] = max(d[i-1], d[i-2] + array[i])


print(d[n-1])

 

 πŸ«±κ²½μš°μ˜ 수 

 

   i-2 i-1 ν˜„μž¬

ㅁㅁ ㅁ ㅁ

1 ) i-2번째 μ‹λŸ‰μ„ ν„΄λ‹€λ©΄ : ν˜„μž¬ μ‹λŸ‰μ„ ν„Έ 수 μžˆλ‹€.

2) i-1번째 μ‹λŸ‰μ„ ν„΄λ‹€λ©΄ : ν˜„μž¬ μ‹λŸ‰μ„ ν„Έ 수 μ—†λ‹€.

 

즉 i-2번째 μ‹λŸ‰ + ν˜„μž¬ μ‹λŸ‰ VS i-1 번째 μ‹λŸ‰ 쀑 더 λ§Žμ€ μ‹λŸ‰μ„ ν„Έ 수 μžˆλŠ” 경우λ₯Ό μ„ νƒν•˜λ©΄ λœλ‹€.

 

πŸ«±κ΅¬ν˜„ μš”μ†Œ

dλŠ” 더 λ§Žμ€ μ‹λŸ‰μ„ ν„Έ 수 μžˆλŠ” κ²½μš°κ°€ μ €μž₯된 dp ν…Œμ΄λΈ”μ΄λ‹€. 

μΈλ±μŠ€μ— λ”°λΌμ„œ μ°¨λ‘€λŒ€λ‘œ ν˜„μž¬ μΈλ±μŠ€κΉŒμ§€ 쀑 κ°€μž₯ μ‹λŸ‰μ„ 많이 ν„Έ 수 μžˆλŠ” 방법이 μ„ νƒλœλ‹€.

for i in range(2,n):
  d[i] = max(d[i-1], d[i-2] + array[i])

3️⃣싀전 문제 3 : λ°”λ‹₯ 곡사 

* 타일링 문제 

 

κ΅¬ν•˜κ³ μž ν•˜λŠ” 것 : κ°€λ‘œ * μ„Έλ‘œ = N * 2 인 λ°”λ‹₯을 μ±„μš°λŠ” λͺ¨λ“  경우의 수 

좜λ ₯ : λ°”λ‹₯을 μ±„μš°λŠ” 방법을 796796으둜 λ‚˜λˆˆ λ‚˜λ¨Έμ§€ 

n = int(input())

d = [0] * 1001

d[1]= 1
d[2]=3


for i in range(3,n+1):
  d[i] = (d[i-1] + d[i-2] *2) % 796796

print(d[n])

 

근데 μ½”λ“œκ°€ 이해가 μ•ˆλœλ‹€.

 

d[1] 은 1κ°€μ§€ 경우

d[2] 은 3κ°€μ§€ κ²½μš°κ°€ μžˆλ‹€.

 

d[3] 은 d[2] + d[1] * 2   = 5κ°€μ§€ 경우의 수λ₯Ό κ°€μ§„λ‹€.

 

d[4] λŠ” d[3] + d[2] * 2  =11κ°€μ§€ 의 경우의 수λ₯Ό κ°€μ§„λ‹€. 

 

이해가 μ•ˆκ°”λ˜ 뢀뢄은 2칸이 λ‚¨μ•˜μ„ λ•Œ κ°€λ‘œ * μ„Έλ‘œ = 1*2 인 타일 2κ°œλ‘œλ„ ꡬ성할 수 μžˆλŠ”λ° μ™œ 이건 κ³ λ €ν•˜μ§€ μ•Šμ„κΉŒ? μ‹Άμ—ˆλŠ”λ° 이건 1칸이 남은 κ²½μš°μ—μ„œ κ³ λ €λ˜λŠ” κ²ƒμ΄μ—ˆλ‹€. κ΅¬μ„±λ˜λŠ” 타일 ν˜•νƒœκ°€ λ™μΌν•˜λ―€λ‘œ μ—¬κΈ°μ„œ κ³ λ €λ˜λŠ” κ²ƒμ΄μ—ˆλ‹€! πŸ€—


4️⃣싀전 문제 4 : 효율적인 화폐 ꡬ성 문제 풀어보기

μœΌμ•„..... dp λ¬Έμ œλŠ” μ–΄λ–»κ²Œ ν’€μ–΄μ•Όν• μ§€ ν˜Όμžμ„œλŠ” 아직 감이 μ•ˆμž‘νžŒλ‹€. 문제 풀이λ₯Ό λ‹¨κ³„λ³„λ‘œ μ •λ¦¬ν•΄λ³΄μž!!! 

 

예λ₯Ό λ“€μ–΄ N = 3이고 K= 7이라고 μƒκ°ν•΄λ³΄μž ! μ—¬κΈ°μ„œ KλŠ” ν™”νμ˜ λ‹¨μœ„λ₯Ό μ˜λ―Έν•œλ‹€.

각 ν™”νμ˜ λ‹¨μœ„λŠ” 2, 3, 5이닀.

🫱 경우의 수

κΈˆμ•‘ iλ₯Ό λ§Œλ“€ 수 μžˆλŠ” 화폐 개수 ai, 화폐 λ‹¨μœ„ k라고 ν•  λ•Œ

a i-kλŠ” κΈˆμ•‘ i-kλ₯Ό λ§Œλ“€ 수 μžˆλŠ” μ΅œμ†Œν•œμ˜ 화폐 개수 

 

ai-k λ₯Ό λ§Œλ“œλŠ” 방법이 μ‘΄μž¬ν•  경우 : a i = min(ai, ai-k + 1)

- ai-kλŠ” a[i]에 κΈˆμ•‘ kλ₯Ό ν•˜λ‚˜ λ”ν•˜λ©΄ λ§Œλ“€ 수 μžˆλ‹€.

μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” 경우 : ai = 10,001

🫱초기 리슀트 μ„€μ •ν•˜κΈ° 

각 인덱슀λ₯Ό 10,001둜 μ„€μ •ν•œλ‹€. 

우리 λ¬Έμ œμ—μ„œ κΈˆμ•‘μ˜ μ΅œλŒ€κ°’μ€ 10,000이닀. λ”°λΌμ„œ 10,001은 λΆˆκ°€λŠ₯ν•œ κΈˆμ•‘μ΄λ‹€. 즉, νŠΉμ • κΈˆμ•‘μ„ λ§Œλ“€ 수 μžˆλŠ” 화폐 ꡬ성이 κ°€λŠ₯ν•˜μ§€ μ•Šλ‹€λŠ” μ˜λ―Έμ΄λ‹€.

0μ›μ˜ 경우, 화폐λ₯Ό ν•˜λ‚˜λ„ μ‚¬μš©ν•˜μ§€ μ•Šμ•˜μ„ λ•Œ λ§Œλ“€ 수 μžˆμœΌλ―€λ‘œ 0인덱슀 κ°’μœΌλ‘œ 0을 μ„€μ •ν•œλ‹€.

 

πŸ«±ν™”ν λ‹¨μœ„ ν™•μΈν•˜κΈ° 

ν˜„μž¬ μ—°μ‚°μ—μ„œ κ°€μž₯ μ΅œμ†Œμ˜ κ°’μœΌλ‘œ λ§Œλ“œλŠ” 연산을 μ„ νƒν•˜λ©΄ λœλ‹€. 

λ”°λΌμ„œ κ°€μž₯ μ΅œμ†Œλ‘œ λ§Œλ“œλŠ” 연산은 μ„ νƒν•˜κ³  이λ₯Ό λ°˜λ³΅ν•΄μ„œ μˆ˜ν–‰ν•˜λ©΄ λœλ‹€.

 

κ°€μž₯ λ¨Όμ € 첫 번째 ν™”νλ‹¨μœ„μΈ 2λΆ€ν„° ν™•μΈν•΄λ³΄μž.

2둜 λ§Œλ“€ 수 μžˆλŠ” μˆ˜λΆ€ν„° dp ν…Œμ΄λΈ”μ„ κ°±μ‹ ν•˜κΈ°

 

인덱슀 2의 경우 1μ΄λΌλŠ” 값을 κ°€μ§€λŠ”λ° μ΄λŠ” 2원 짜리 화폐 ν•˜λ‚˜λ₯Ό μ΄μš©ν•˜μ—¬ 2원을 λ§Œλ“€ 수 μžˆλ‹€λŠ” μ˜λ―Έμ΄λ‹€. 

인덱슀 4의 경우 2λΌλŠ” 값을 κ°€μ§€λŠ”λ° μ΄λŠ” 2원 짜리 화폐 2개λ₯Ό μ΄μš©ν•˜μ—¬ 2+2 = 4원을 λ§Œλ“€ 수 μžˆλ‹€λŠ” μ˜λ―Έμ΄λ‹€.

λͺ‡ μΈλ±μŠ€λŠ” 10,001 값을 κ°€μ§€λŠ”λ°, μ΄λŠ” 2μ›μœΌλ‘œ κ΅¬μ„±ν• μˆ˜ μ—†λŠ” κΈˆμ•‘μ΄κΈ° λ•Œλ¬Έμ΄λ‹€.

 

A2 = A0 + 1

A4 = A2 + 1

 

이제 화폐 λ‹¨μœ„ 3을 ν™•μΈν•΄λ³΄μž

2와 3으둜 λ§Œλ“€ 수 μžˆλŠ” μˆ˜λΆ€ν„° dp ν…Œμ΄λΈ”μ„ κ°±μ‹ ν•˜κΈ°

 

A5 = A2 + 1

인덱슀 5λŠ” 2λΌλŠ” 값을 κ°€μ§€λŠ”λ° μ΄λŠ” 2μ›μ§œλ¦¬ 화폐 1개, 3μ›μ§œλ¦¬ 화폐 1개둜 2 + 3 = 5원을 λ§Œλ“€ 수 μžˆλ‹€λŠ” μ˜λ―Έμ΄λ‹€.

 

이제 화폐 λ‹¨μœ„ 5을 ν™•μΈν•΄λ³΄μž

2, 3, 5둜 λ§Œλ“€ 수 μžˆλŠ” μˆ˜λΆ€ν„° dp ν…Œμ΄λΈ”μ„ κ°±μ‹ ν•˜κΈ°

 

A 7 = A2 + 1둜 2λΌλŠ” 값을 κ°€μ§„λ‹€. 2μ›μ§œλ¦¬ 화폐 ν•˜λ‚˜λž‘ 5μ›μ§œλ¦¬ 화폐 1개둜 2 + 5 = 7원을 λ§Œλ“€ 수 μžˆλ‹€λŠ” μ˜λ―Έμ΄λ‹€.

μ›λž˜ 이전 λ‹¨κ³„μ—μ„œ A7의 값은 3μ΄μ—ˆλŠ—λ„€, μ΄λŠ” 2 + 2 + 3 = 7μ›μœΌλ‘œ 3개의 화폐λ₯Ό μ‚¬μš©ν–ˆμ„ λ•Œλ₯Ό λ‚˜νƒ€λ‚Έ 것이닀.

 

κ·ΈλŸ¬λ‚˜ 2 + 5 = 7원을 λ§Œλ“€λ©΄ 화폐λ₯Ό 2개만 μ‚¬μš©ν•΄λ„ λ˜λ―€λ‘œ κ°±μ‹ λœλ‹€.

 

결과적으둜 7원을 λ§Œλ“€κΈ° μœ„ν•œ μ΅œμ†Œμ˜ 화폐 κ°œμˆ˜λŠ” 2κ°œμ΄λ‹€.

 

# μž…λ ₯λ°›κΈ°
n,m = int(input().split)
n_list=[]

for _ in range(n):
  n_list.append(int(input().split()))

# ν•œλ²ˆ κ³„μ‚°λœ κ²°κ³Όλ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•œ DP ν…Œμ΄λΈ” μ΄ˆκΈ°ν™”
d = [100001] * (m+1)

# dp κ΅¬ν˜„

d[0]= 0
for i in range(n):
  for j in range(n_list[i] , m + 1):
    if d[j - n_list[i]] != 10001:
      d[j] = min( d[j], d[ j - n_list[i] ] +1)

if d[m] == 10001:
  print(-1)
else:
  print(d[m])

 

 

이 λ‘œμ§μ„ λ‹€μ‹œ μ΄ν•΄ν•΄λ³΄μž ! ! ! 

 

μœ„μ—μ„œ μ•Œμ•„λ³Έ κ²ƒμ²˜λŸΌ 화폐 λ‹¨μœ„ λ³„λ‘œ dp ν…Œμ΄λΈ”κ°±μ‹ 

for i in range(n):
  for j in range(n_list[i] , m + 1):
    if d[j - n_list[i]] != 10001:
      d[j] = min( d[j], d[ j - n_list[i] ] +1)

 

μ—¬κΈ°μ„œ d[j - n_list[i]] 와 n_list[i]λ₯Ό λ”ν•˜λ©΄ μ›ν•˜λŠ” κΈˆμ•‘μ΄ λœλ‹€

λ”°λΌμ„œ d[j]와 이전 κΈˆμ•‘μ— κΈˆμ•‘μ„ λ”ν•΄μ„œ 얻은 수 쀑 μž‘μ€ 것을 νƒν•˜λ©΄ λœλ‹€.


λ°±μ€€μ˜ 1,2,3 λ§Œλ“€κΈ° 문제 풀어보기 

https://www.acmicpc.net/problem/9095

 

test = int(input())

def sum_func(x):
  if x==1:
    return 1
  elif x==2:
    return 2
  elif x==3:
    return 4
  else:
    return sum_func(x-1) + sum_func(x-2) + sum_func(x-3)
  
                             
for _ in range(0,test):
  n = int(input())
  print(sum_func(n))

 

κ·œμΉ™μ„ μ°Ύμ•„λ‚΄λŠ” 것이 μ€‘μš”ν•˜λ‹€. 그리고 이전 κ²°κ³Όλ₯Ό μ–΄λ–»κ²Œ μ‚¬μš©ν•  수 μžˆλŠ”μ§€ 잘 μƒκ°ν•΄λ³΄μž.

κ·œμΉ™μ„ λͺ¨λ₯Ό λ•Œμ—λŠ” ν•œλ²ˆ n = 1일 λ•Œ 2일 λ•Œλ₯Ό 생각해보며 λ‚˜μ—΄ν•΄λ³΄μž 

n=4인 경우

1, 2, 3을 λ”ν•΄μ„œ λ‚˜νƒ€λ‚΄λ €λ©΄ κ²½μš°λŠ” μ•„λž˜ 3κ°€μ§€ μΌ€μ΄μŠ€λ‘œ λ‚˜λ‰œλ‹€. 

 

1 + 3

1에 3을 λ”ν•˜λŠ” 경우의 μˆ˜λŠ” 3을 κ΅¬μ„±ν•˜λŠ” 경우의 μˆ˜μ™€ λ™μΌν•˜λ‹€ 

μ—¬κΈ°μ„œλŠ” 1 + 1+ 1 , 1 + 2, 2 + 1 , 3 으둜 4κ°€μ§€ κ²½μš°κ°€ μžˆλ‹€.

 

2 + 2 

2에 2을 λ”ν•˜λŠ” 경우의 μˆ˜λŠ” 2을 κ΅¬μ„±ν•˜λŠ” 경우의 μˆ˜μ™€ λ™μΌν•˜λ‹€ 

μ—¬κΈ°μ„œλŠ” 1 + 1, 2 둜 2κ°€μ§€ κ²½μš°κ°€ μžˆλ‹€.

 

3 + 1

3에 1을 λ”ν•˜λŠ” 경우의 μˆ˜λŠ” 1을 κ΅¬μ„±ν•˜λŠ” 경우의 μˆ˜μ™€ λ™μΌν•˜λ‹€  

μ—¬κΈ°μ„œλŠ” 1둜 1κ°€μ§€ κ²½μš°κ°€ μžˆλ‹€.

 

 

μ΄λ ‡κ²Œ μž‘μ„±ν•΄λ³΄λ‹ˆ 각 κ²½μš°λ§ˆλ‹€ κ·œμΉ™μ„ μ•Œ 수 μžˆμ—ˆλ‹€.

4λ₯Ό κ΅¬μ„±ν•˜λŠ” 경우의 μˆ˜λŠ” 3을 κ΅¬μ„±ν•˜λŠ” 경우의 수 + 2λ₯Ό κ΅¬μ„±ν•˜λŠ” 경우의 수 + 1을 κ΅¬μ„±ν•˜λŠ” 경우의 수 둜 ν‘œν˜„λ˜μ—ˆλ‹€.

5λ₯Ό κ΅¬μ„±ν•˜λŠ” 경우의 μˆ˜λ„ 4λ₯Ό κ΅¬μ„±ν•˜λŠ” 경우의 수 + 3을 κ΅¬μ„±ν•˜λŠ” 경우의 수 + 2λ₯Ό κ΅¬μ„±ν•˜λŠ” 경우의 수둜 ν‘œν˜„λ˜μ—ˆλ‹€.

 

λ”°λΌμ„œ xλΌλŠ” 합을 κ΅¬μ„±ν•˜λŠ” 경우의 μˆ˜λŠ” μ•„λž˜μ™€ 같이 ν‘œν˜„ν•  수 μžˆλ‹€.

sum_func(x-1) + sum_func(x-2) + sum_func(x-3)

 

728x90