🐍 μ½”λ”©ν…ŒμŠ€νŠΈ λŒ€λΉ„ : PS

[ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€] μŠ€ν‹°μ»€ λͺ¨μœΌκΈ°(2) (level3, python)

개발자 HOON 2022. 10. 14. 14:16

🏝 문제 μ„€λͺ…

 

 

N개의 μŠ€ν‹°μ»€κ°€ μ›ν˜•μœΌλ‘œ μ—°κ²°λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒ 그림은 N = 8인 경우의 μ˜ˆμ‹œμž…λ‹ˆλ‹€.


μ›ν˜•μœΌλ‘œ μ—°κ²°λœ μŠ€ν‹°μ»€μ—μ„œ λͺ‡ μž₯의 μŠ€ν‹°μ»€λ₯Ό λœ―μ–΄λ‚΄μ–΄ λœ―μ–΄λ‚Έ μŠ€ν‹°μ»€μ— 적힌 숫자의 합이 μ΅œλŒ€κ°€ λ˜λ„λ‘ ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. 단 μŠ€ν‹°μ»€ ν•œ μž₯을 λœ―μ–΄λ‚΄λ©΄ μ–‘μͺ½μœΌλ‘œ μΈμ ‘ν•΄μžˆλŠ” μŠ€ν‹°μ»€λŠ” μ°’μ–΄μ Έμ„œ μ‚¬μš©ν•  수 μ—†κ²Œ λ©λ‹ˆλ‹€.

 

예λ₯Ό λ“€μ–΄ μœ„ κ·Έλ¦Όμ—μ„œ 14κ°€ 적힌 μŠ€ν‹°μ»€λ₯Ό 뜯으면 μΈμ ‘ν•΄μžˆλŠ” 10, 6이 적힌 μŠ€ν‹°μ»€λŠ” μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€. μŠ€ν‹°μ»€μ— 적힌 μˆ«μžκ°€ λ°°μ—΄ ν˜•νƒœλ‘œ μ£Όμ–΄μ§ˆ λ•Œ, μŠ€ν‹°μ»€λ₯Ό λœ―μ–΄λ‚΄μ–΄ 얻을 수 μžˆλŠ” 숫자의 ν•©μ˜ μ΅œλŒ“κ°’μ„ return ν•˜λŠ” solution ν•¨μˆ˜λ₯Ό μ™„μ„±ν•΄ μ£Όμ„Έμš”. μ›ν˜•μ˜ μŠ€ν‹°μ»€ λͺ¨μ–‘을 μœ„ν•΄ λ°°μ—΄μ˜ 첫 번째 μ›μ†Œμ™€ λ§ˆμ§€λ§‰ μ›μ†Œκ°€ μ„œλ‘œ μ—°κ²°λ˜μ–΄ μžˆλ‹€κ³  κ°„μ£Όν•©λ‹ˆλ‹€.


μ œν•œ 사항
  • stickerλŠ” μ›ν˜•μœΌλ‘œ μ—°κ²°λœ μŠ€ν‹°μ»€μ˜ 각 칸에 적힌 μˆ«μžκ°€ μˆœμ„œλŒ€λ‘œ λ“€μ–΄μžˆλŠ” λ°°μ—΄λ‘œ, 길이(N)λŠ” 1 이상 100,000 μ΄ν•˜μž…λ‹ˆλ‹€.
  • sticker의 각 μ›μ†ŒλŠ” μŠ€ν‹°μ»€μ˜ 각 칸에 적힌 숫자이며, 각 칸에 적힌 μˆ«μžλŠ” 1 이상 100 μ΄ν•˜μ˜ μžμ—°μˆ˜μž…λ‹ˆλ‹€.
  • μ›ν˜•μ˜ μŠ€ν‹°μ»€ λͺ¨μ–‘을 μœ„ν•΄ sticker λ°°μ—΄μ˜ 첫 번째 μ›μ†Œμ™€ λ§ˆμ§€λ§‰ μ›μ†Œκ°€ μ„œλ‘œ μ—°κ²°λ˜μ–΄μžˆλ‹€κ³  κ°„μ£Όν•©λ‹ˆλ‹€.

μž…μΆœλ ₯ 예
[14, 6, 5, 11, 3, 9, 2, 10] 36
[1, 3, 2, 5, 4] 8

μž…μΆœλ ₯ 예 μ„€λͺ…

 

μž…μΆœλ ₯ 예 #1
6, 11, 9, 10이 적힌 μŠ€ν‹°μ»€λ₯Ό λ–Όμ–΄ λƒˆμ„ λ•Œ 36으둜 μ΅œλŒ€κ°€ λ©λ‹ˆλ‹€.

 

μž…μΆœλ ₯ 예 #2
3, 5κ°€ 적힌 μŠ€ν‹°μ»€λ₯Ό λ–Όμ–΄ λƒˆμ„ λ•Œ 8둜 μ΅œλŒ€κ°€ λ©λ‹ˆλ‹€.


 

🏝 풀이 μ½”λ“œ

def solution(sticker):
    answer = 0
    if len(sticker) == 1:
        return sticker.pop()

    size = len(sticker)
    # 1번 μ„ νƒν•˜λŠ” 경우 -> 1..n-1번 배열에 λŒ€ν•œ DP
    dp1 = [0] + sticker[:-1]
    for i in range(2, size):
        dp1[i] = max(dp1[i-1], dp1[i-2] + dp1[i])
    
    # 2번 μ„ νƒν•˜λŠ” 경우 -> 2...n번 배열에 λŒ€ν•œ DP
    dp2 = [0] + sticker[1:]
    for i in range(2, size):
        dp2[i] = max(dp2[i-1], dp2[i-2] + dp2[i])
        
    answer = max(dp1[-1], dp2[-1])
    return answer

 

μ›ν˜• DP에 λŒ€ν•œ λ¬Έμ œμ΄λ‹€.

μš°μ„ , μ›ν˜•μ΄λΌλŠ” νŠΉμ§•μ„ μ œκ±°ν•˜κ³  문제λ₯Ό λ°”λΌλ³΄μž.

 

주어진 [14, 6, 5, 11, 3, 9, 2, 10] 배열을 가지고 μ–΄λ–»κ²Œ 선택을 ν•΄μ•Ό 쒋을 지 μƒκ°ν•΄λ³΄μž.

이 배열을 DP λ°°μ—΄λ‘œ λ§Œλ“€κ³ , 각 μžλ¦¬λ§ˆλ‹€ ν•΄λ‹Ή μœ„μΉ˜κΉŒμ§€μ˜ 졜적의 ν•΄λ₯Ό μ €μž₯ν•΄λ³΄μž.

 

[14]만 주어진 배열이라면, 14λ₯Ό μ„ νƒν•˜λŠ” 것이 μ΅œμ μ΄λ‹€.

[14, 6]이 주어진 배열인 경우, μƒˆλ‘œ λ“€μ–΄μ˜¨ 6을 μ„ νƒν•˜λ©΄ 14λ₯Ό μ„ νƒν•˜μ§€ λͺ»ν•œλ‹€. 14κ°€ 더 ν¬λ―€λ‘œ 14λ₯Ό μ„ νƒν•˜λŠ” 것이 μ΅œμ μ΄λ‹€, λ”°λΌμ„œ DP배열은 [14, 6]  [14, 14]둜 λ³€ν™”ν•œλ‹€.

κΈ°μ‘΄ λ°°μ—΄ [14, 6, 5]의 경우λ₯Ό 보자. μƒˆλ‘œ λ“€μ–΄μ˜¨ 5λ₯Ό μ„ νƒν•˜κ²Œ 되면, 6은 μ„ νƒν•˜μ§€ λͺ»ν•˜μ§€λ§Œ, μ•žμ˜ 14λŠ” 선택이 κ°€λŠ₯ν•˜λ‹€. 5λ₯Ό μ„ νƒν•˜μ§€ μ•Šκ³  6을 μ„ νƒν•˜λ©΄ 14도 μ„ νƒν•˜μ§€ λͺ»ν•˜λ―€λ‘œ, 19 > 6μ΄λ―€λ‘œ 19λ₯Ό μ„ νƒν•˜λŠ” 것이 μ΅œμ μ΄λ‹€. λ”°λΌμ„œ DP 배열은 [14, 14, 5]  [14, 14, 19]이닀.

 

쑰금만 더 보자.

κΈ°μ‘΄ λ°°μ—΄ [14, 6, 5, 11]의 경우, μƒˆλ‘œ λ“€μ–΄μ˜¨ 11을 μ„ νƒν•˜κ²Œ 되면 5λŠ” μ„ νƒν•˜μ§€ λͺ»ν•˜μ§€λ§Œ, 6μ΄λ‚˜ 14λ₯Ό 선택할 수 μžˆλ‹€. μ—¬κΈ°μ„œ 6을 μ„ νƒν•˜κ²Œ 되면 14λ₯Ό μ„ νƒν•˜μ§€ λͺ»ν•˜λ‹ˆ, 11 + 14λ₯Ό ν•˜λŠ” 것이 더 μ˜³λ‹€. 14 + 5의 쑰합보닀 더 ν¬λ―€λ‘œ, 25κ°€ μ„ νƒλ˜λŠ” 것이 μ˜³λ‹€. λ”°λΌμ„œ DP 배열은 [14, 14, 19, 11] → [14, 14, 19, 25]κ°€ λœλ‹€.

 

μ—¬κΈ°μ„œ μ•½κ°„μ˜ 점화식을 μ΄λŒμ–΄ λ‚Ό 수 μžˆλ‹€.

각 λ°°μ—΄μ˜ μ‚¬μ΄μ¦ˆλ₯Ό ν•˜λ‚˜μ”© λŠ˜λ €κ°€λ©΄μ„œ 'μƒˆλ‘œ λ“€μ–΄μ˜¨ 수'λ₯Ό κΈ°μ€€μœΌλ‘œ λ“€μ—ˆλ‹€.

그리고 [14, 6, 5, 11]μ—μ„œ λ³΄μ•˜λ“―μ΄, 11을 μ„ νƒν–ˆλ‹€κ³  ν•΄μ„œ λ°”λ‘œ 5λ₯Ό μ œμ™Έν•œ μ•žμ˜ 값인 6을 μ„ νƒν•œ 것이 μ•„λ‹ˆλΌ, 14λ₯Ό μ„ νƒν–ˆλ‹€.

κΈ°μ‘΄ λ°°μ—΄μ—μ„œλŠ” 점화식을 μ°ΎκΈ° μ–΄λ ΅μ§€λ§Œ, DP λ°°μ—΄μ—μ„œλŠ” 쑰금 보일 수 μžˆλ‹€.

 

DPλ°°μ—΄μ—μ„œ DP[i] = max(DP[i] + DP[i-2], DP[i-1])μ΄λΌλŠ” 식을 이끌 수 μžˆλŠ”λ°, 이λ₯Ό ν•΄μ„ν•˜λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

DP[i] = μ΅œλŒ“κ°’(μƒˆλ‘œ λ“€μ–΄μ˜¨ 수 + 2μΉΈ μ „κΉŒμ§€μ˜ 졜적의 κ°’, 1μΉΈ μ „μ˜ 졜적의 κ°’)

 

ν•˜μ§€λ§Œ, μ—¬κΈ°μ„œ μ›ν˜•μ΄λΌλŠ” 쑰건이 μžˆλ‹€. 0번 인덱슀의 μŠ€ν‹°μ»€λ₯Ό λ–Όλ©΄ -1번 인덱슀의 μŠ€ν‹°μ»€λŠ” μ‚¬μš©ν•˜μ§€ λͺ»ν•˜λŠ” 것이닀.

λ”°λΌμ„œ 두 κ°€μ§€μ˜ 경우둜 λΆ„λ¦¬ν•΄μ„œ μƒκ°ν•΄λ³΄μž.

1) 0번 인덱슀의 μŠ€ν‹°μ»€λ₯Ό λ–ΌλŠ” 경우

2) 1번 인덱슀의 μŠ€ν‹°μ»€λ₯Ό λ–ΌλŠ” 경우

 

1λ²ˆμ€, λ§ˆμ§€λ§‰ 인덱슀의 μŠ€ν‹°μ»€λŠ” 무쑰건 μ‚¬μš©ν•˜μ§€ λͺ»ν•œλ‹€. λ”°λΌμ„œ λ§ˆμ§€λ§‰ μš”μ†Œλ₯Ό μ œκ±°ν•œ [:-1] λ²”μœ„μ— λŒ€ν•΄μ„œ DPλ₯Ό ν•œ 번 λŒλ¦°λ‹€.

2λ²ˆμ€, 0번 인덱슀의 μŠ€ν‹°μ»€λŠ” 무쑰건 μ‚¬μš©ν•˜μ§€ λͺ»ν•œλ‹€. λ”°λΌμ„œ κ°€μž₯ μ•ž μš”μ†Œλ₯Ό μ œκ±°ν•œ [1:] λ²”μœ„μ— λŒ€ν•΄μ„œ DPλ₯Ό ν•œ 번 λŒλ¦°λ‹€.

각 경우의 μ΅œλŒ“κ°’λ“€ 쀑 μ΅œλŒ“κ°’μ΄ 정닡이 λœλ‹€.

 

λ˜ν•œ 점화식 μžμ²΄κ°€ i-2κΉŒμ§€ λ‚˜μ˜€κΈ° λ•Œλ¬Έμ— 주어진 λ°°μ—΄μ˜ 인덱슀 μ—λŸ¬κ°€ λ‚˜μ§€ μ•Šλ„λ‘ μ£Όμ˜ν•˜μ—¬μ•Ό ν•œλ‹€.

μ›ν™œν•œ 계산을 μœ„ν•΄ [:-1]λ°°μ—΄κ³Ό [1:] λ°°μ—΄ λͺ¨λ‘ μ•žμ— [0]을 μΆ”κ°€ν•΄μ£Όμ—ˆλ‹€. 점화식이 λ§μ…ˆ 연산이라 결과에 영ν–₯을 λ―ΈμΉ˜μ§€λ„ μ•Šκ³  κ΅¬ν˜„λ„ νŽΈλ¦¬ν•˜κ²Œ λ„μ™€μ£ΌλŠ” μŠ€ν‚¬μ΄μ—ˆλ‹€.

 

- μ›ν˜• DPλ₯Ό ν‘ΈλŠ” 방법

1. μ›ν˜• 쑰건을 μ œκ±°ν•œ μƒνƒœμ—μ„œ DP의 점화식 이끌기

2. μ›ν˜• 쑰건은 2가지 μΌ€μ΄μŠ€λ‘œ λΆ„λ¦¬ν•΄μ„œ DP 연산을 각 μΌ€μ΄μŠ€λ§ˆλ‹€ 돌리고 κ²°κ³Ό 반영

 

2022.10.14 - [🐍 μ½”λ”©ν…ŒμŠ€νŠΈ λŒ€λΉ„ : PS] - [ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€] λ„λ‘‘μ§ˆ (level4, python)

 

[ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€] λ„λ‘‘μ§ˆ (level4, python)

🏝 문제 μ„€λͺ… 도둑이 μ–΄λŠ λ§ˆμ„μ„ ν„Έ κ³„νšμ„ ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 이 λ§ˆμ„μ˜ λͺ¨λ“  집듀은 μ•„λž˜ κ·Έλ¦Όκ³Ό 같이 λ™κ·Έλž—κ²Œ λ°°μΉ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. 각 집듀은 μ„œλ‘œ μΈμ ‘ν•œ 집듀과 λ°©λ²”μž₯μΉ˜κ°€ μ—°κ²°λ˜μ–΄ 있기 λ•Œ

hoons-dev.tistory.com

 

μœ„ λ¬Έμ œμ™€ μ™„μ „νžˆ λ™μΌν•˜λ©°, ν’€μ΄μ½”λ“œ μ—­μ‹œ λ™μΌν•˜λ‹€. ν•œ 번 더 μ—°μŠ΅μ΄ ν•„μš”ν•˜λ‹€λ©΄ 이 문제둜 λ³΅μŠ΅ν•˜λŠ” 것도 μ’‹λ‹€.