ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [DP] μ—°μ†ν•˜λŠ” 것을 선택할 수 없을 λ•Œ (BOJ 2579, 2156)
    Algorithms in Python/baekjoon 2021. 1. 18. 03:27

    🎈 λ°±μ€€ 2579 계단 였λ₯΄κΈ°

    문제

    계단 였λ₯΄κΈ° κ²Œμž„μ€ 계단 μ•„λž˜ μ‹œμž‘μ λΆ€ν„° 계단 κΌ­λŒ€κΈ°μ— μœ„μΉ˜ν•œ λ„μ°©μ κΉŒμ§€ κ°€λŠ” κ²Œμž„μ΄λ‹€. <κ·Έλ¦Ό 1>κ³Ό 같이 각각의 κ³„λ‹¨μ—λŠ” μΌμ •ν•œ μ μˆ˜κ°€ μ“°μ—¬ μžˆλŠ”λ° 계단을 밟으면 κ·Έ 계단에 μ“°μ—¬ μžˆλŠ” 점수λ₯Ό μ–»κ²Œ λœλ‹€.

    예λ₯Ό λ“€μ–΄ <κ·Έλ¦Ό 2>와 같이 μ‹œμž‘μ μ—μ„œλΆ€ν„° 첫 번째, 두 번째, λ„€ 번째, μ—¬μ„― 번째 계단을 λ°Ÿμ•„ 도착점에 λ„λ‹¬ν•˜λ©΄ 총 μ μˆ˜λŠ” 10 + 20 + 25 + 20 = 75점이 λœλ‹€.

    계단 였λ₯΄λŠ” λ°λŠ” λ‹€μŒκ³Ό 같은 κ·œμΉ™μ΄ μžˆλ‹€.

    1. 계단은 ν•œ λ²ˆμ— ν•œ 계단씩 λ˜λŠ” 두 계단씩 였λ₯Ό 수 μžˆλ‹€. 즉, ν•œ 계단을 λ°ŸμœΌλ©΄μ„œ μ΄μ–΄μ„œ λ‹€μŒ κ³„λ‹¨μ΄λ‚˜, λ‹€μŒ λ‹€μŒ κ³„λ‹¨μœΌλ‘œ 였λ₯Ό 수 μžˆλ‹€.
    2. μ—°μ†λœ μ„Έ 개의 계단을 λͺ¨λ‘ λ°Ÿμ•„μ„œλŠ” μ•ˆ λœλ‹€. 단, μ‹œμž‘μ μ€ 계단에 ν¬ν•¨λ˜μ§€ μ•ŠλŠ”λ‹€.
    3. λ§ˆμ§€λ§‰ 도착 계단은 λ°˜λ“œμ‹œ λ°Ÿμ•„μ•Ό ν•œλ‹€.

    λ”°λΌμ„œ 첫 번째 계단을 밟고 이어 두 번째 κ³„λ‹¨μ΄λ‚˜, μ„Έ 번째 κ³„λ‹¨μœΌλ‘œ 였λ₯Ό 수 μžˆλ‹€. ν•˜μ§€λ§Œ, 첫 번째 계단을 밟고 이어 λ„€ 번째 κ³„λ‹¨μœΌλ‘œ μ˜¬λΌκ°€κ±°λ‚˜, 첫 번째, 두 번째, μ„Έ 번째 계단을 μ—°μ†ν•΄μ„œ λͺ¨λ‘ λ°Ÿμ„ μˆ˜λŠ” μ—†λ‹€.

    각 계단에 μ“°μ—¬ μžˆλŠ” μ μˆ˜κ°€ μ£Όμ–΄μ§ˆ λ•Œ 이 κ²Œμž„μ—μ„œ 얻을 수 μžˆλŠ” 총 점수의 μ΅œλŒ“κ°’μ„ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

    μž…λ ₯

    μž…λ ₯의 첫째 쀄에 κ³„λ‹¨μ˜ κ°œμˆ˜κ°€ 주어진닀.

    λ‘˜μ§Έ 쀄뢀터 ν•œ 쀄에 ν•˜λ‚˜μ”© 제일 μ•„λž˜μ— 놓인 계단뢀터 μˆœμ„œλŒ€λ‘œ 각 계단에 μ“°μ—¬ μžˆλŠ” μ μˆ˜κ°€ 주어진닀. κ³„λ‹¨μ˜ κ°œμˆ˜λŠ” 300μ΄ν•˜μ˜ μžμ—°μˆ˜μ΄κ³ , 계단에 μ“°μ—¬ μžˆλŠ” μ μˆ˜λŠ” 10,000μ΄ν•˜μ˜ μžμ—°μˆ˜μ΄λ‹€.

    좜λ ₯

    첫째 쀄에 계단 였λ₯΄κΈ° κ²Œμž„μ—μ„œ 얻을 수 μžˆλŠ” 총 점수의 μ΅œλŒ“κ°’μ„ 좜λ ₯ν•œλ‹€.

     


    ❗ 문제의 핡심

     κ³„단은 ν•œ λ²ˆμ— ν•œ 계단 or 두 계단씩 였λ₯Ό 수 μžˆλ‹€.

     μ—°μ†λœ μ„Έ 개의 계단을 λͺ¨λ‘ 밟으면 μ•ˆλœλ‹€. μ‹œμž‘μ μ€ 계단에 포함x

    => μ•ž κ³„λ‹¨κΉŒμ§€μ˜ 점수의 μ΅œλŒ“κ°’μ„ μ΄μš©ν•˜μ—¬ μ°¨λ‘€λŒ€λ‘œ ν•΄κ²°ν•˜λ©΄ λœλ‹€. *DP 

     

    μ„Έ 번째 계단 μ΄μƒμΌλ•Œ, i번째 계단을 λ°ŸλŠ” 경우의 수

    - i - 2번째 계단을 λ°Ÿμ§€ μ•Šκ³ , i - 1번째 계단을 λ°ŸλŠ” 경우 (X O O)

    - i - 2번째 계단을 밟고, i - 1번째 계단을 λ°Ÿμ§€ μ•ŠλŠ” 경우 (O X O)

    dp[i] = max(dp[i - 3] + arr[i - 1], dp[i - 2]) + arr[i]

     

    βœ… 전체 μ½”λ“œ

    import sys
    input = sys.stdin.readline
    
    n = int(input())
    
    arr = [0] * (n + 1)
    dp = [0] * (n + 1)
    
    for i in range(1, n + 1):
        arr[i] = int(input())
    
    dp[1] = arr[1]
    if n == 1:
        print(dp[1])
        exit(0)
    
    dp[2] = dp[1] + arr[2]
    if n == 2:
        print(dp[2])
        exit(0)
    
    for i in range(3, n + 1):
        dp[i] = max(dp[i - 3] + arr[i - 1], dp[i - 2]) + arr[i]
    
    print(dp[n])

    for 전에 μΈλ±μŠ€κ°€ 1, 2일 λ•Œ 처리λ₯Ό μ•ˆν•˜λ©΄ 인덱슀 였λ₯˜κ°€ λ‚œλ‹€.

     


    πŸŽˆλ°±μ€€ 2156 포도주 μ‹œμ‹

    문제

    νš¨μ£ΌλŠ” 포도주 μ‹œμ‹νšŒμ— κ°”λ‹€. κ·Έ 곳에 κ°”λ”λ‹ˆ, ν…Œμ΄λΈ” μœ„μ— λ‹€μ–‘ν•œ 포도주가 λ“€μ–΄μžˆλŠ” 포도주 μž”μ΄ 일렬둜 놓여 μžˆμ—ˆλ‹€. νš¨μ£ΌλŠ” 포도주 μ‹œμ‹μ„ ν•˜λ €κ³  ν•˜λŠ”λ°, μ—¬κΈ°μ—λŠ” λ‹€μŒκ³Ό 같은 두 가지 κ·œμΉ™μ΄ μžˆλ‹€.

    1. 포도주 μž”μ„ μ„ νƒν•˜λ©΄ κ·Έ μž”μ— λ“€μ–΄μžˆλŠ” ν¬λ„μ£ΌλŠ” λͺ¨λ‘ λ§ˆμ…”μ•Ό ν•˜κ³ , λ§ˆμ‹  ν›„μ—λŠ” μ›λž˜ μœ„μΉ˜μ— λ‹€μ‹œ 놓아야 ν•œλ‹€.
    2. μ—°μ†μœΌλ‘œ 놓여 μžˆλŠ” 3μž”μ„ λͺ¨λ‘ λ§ˆμ‹€ μˆ˜λŠ” μ—†λ‹€.

    νš¨μ£ΌλŠ” 될 수 μžˆλŠ” λŒ€λ‘œ λ§Žμ€ μ–‘μ˜ 포도주λ₯Ό 맛보기 μœ„ν•΄μ„œ μ–΄λ–€ 포도주 μž”μ„ 선택해야 할지 κ³ λ―Όν•˜κ³  μžˆλ‹€. 1λΆ€ν„° nκΉŒμ§€μ˜ λ²ˆν˜Έκ°€ λΆ™μ–΄ μžˆλŠ” n개의 포도주 μž”μ΄ μˆœμ„œλŒ€λ‘œ ν…Œμ΄λΈ” μœ„μ— 놓여 있고, 각 포도주 μž”μ— λ“€μ–΄μžˆλŠ” ν¬λ„μ£Όμ˜ 양이 μ£Όμ–΄μ‘Œμ„ λ•Œ, 효주λ₯Ό 도와 κ°€μž₯ λ§Žμ€ μ–‘μ˜ 포도주λ₯Ό λ§ˆμ‹€ 수 μžˆλ„λ‘ ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€. 

    예λ₯Ό λ“€μ–΄ 6개의 포도주 μž”μ΄ 있고, 각각의 μž”μ— μˆœμ„œλŒ€λ‘œ 6, 10, 13, 9, 8, 1 만큼의 포도주가 λ“€μ–΄ μžˆμ„ λ•Œ, 첫 번째, 두 번째, λ„€ 번째, λ‹€μ„― 번째 포도주 μž”μ„ μ„ νƒν•˜λ©΄ 총 포도주 양이 33으둜 μ΅œλŒ€λ‘œ λ§ˆμ‹€ 수 μžˆλ‹€.

    μž…λ ₯

    첫째 쀄에 포도주 μž”μ˜ 개수 n이 주어진닀. (1≤n≤10,000) λ‘˜μ§Έ 쀄뢀터 n+1번째 μ€„κΉŒμ§€ 포도주 μž”μ— λ“€μ–΄μžˆλŠ” ν¬λ„μ£Όμ˜ 양이 μˆœμ„œλŒ€λ‘œ 주어진닀. ν¬λ„μ£Όμ˜ 양은 1,000 μ΄ν•˜μ˜ 음이 μ•„λ‹Œ μ •μˆ˜μ΄λ‹€.

    좜λ ₯

    첫째 쀄에 μ΅œλŒ€λ‘œ λ§ˆμ‹€ 수 μžˆλŠ” ν¬λ„μ£Όμ˜ 양을 좜λ ₯ν•œλ‹€.

     


    ❗ 문제의 핡심

     μ—°μ†μœΌλ‘œ λ†“μ—¬μžˆλŠ” 3μž”μ„ 선택할 수 μ—†λ‹€.

     μˆœμ„œλŒ€λ‘œ 포도주λ₯Ό μ‹œμ‹/μ‹œμ‹X ν•  λ•Œμ˜ μ΅œλŒ€λ‘œ λ§ˆμ‹€ 수 μžˆλŠ” ν¬λ„μ£Όμ˜ 양을 κ΅¬ν•˜μ—¬μ•Ό ν•œλ‹€.

    μ—°μ†ν•΄μ„œ μ„ νƒν•˜μ§€ μ•Šμ•„λ„ λœλ‹€. (계단 였λ₯΄κΈ° λ¬Έμ œμ™€ λ‹€λ₯Έ 점)

    => ν˜„μž¬ μˆœμ„œλ³΄λ‹€ μ•žμ˜ μˆœμ„œμ˜ ν¬λ„μ£Όμ˜ μ΅œλŒ“κ°’μ„ μ΄μš©ν•˜μ—¬ ν•΄κ²°ν•˜λ©΄ λœλ‹€. *DP

     

    i >= 3 일 λ•Œ, i번째 ν¬λ„μ£Όμ˜ 경우의 μˆ˜λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

    i - 3 i - 2 i - 1 i
      λ§ˆμ‹œμ§€ μ•ŠλŠ”λ‹€ λ§ˆμ‹ λ‹€ λ§ˆμ‹ λ‹€
        λ§ˆμ‹œμ§€ μ•ŠλŠ”λ‹€ λ§ˆμ‹ λ‹€
          λ§ˆμ‹œμ§€ μ•ŠλŠ”λ‹€
    dp[i] = max(dp[i - 3] + arr[i - 1] + arr[i], dp[i - 2] + arr[i], dp[i - 1])

     

    βœ… 전체 μ½”λ“œ

    import sys
    input = sys.stdin.readline
    
    n = int(input())
    
    arr = [0] * (n + 1)
    dp = [0] * (n + 1)
    
    for i in range(1, n + 1):
        arr[i] = int(input())
    
    dp[1] = arr[1]
    if n == 1:
        print(dp[1])
        exit(0)
    
    dp[2] = dp[1] + arr[2]
    if n == 2:
        print(dp[2])
        exit(0)
    
    for i in range(3, n + 1):
        # x o o / x o / x
        dp[i] = max(dp[i - 3] + arr[i - 1] + arr[i], dp[i - 2] + arr[i], dp[i - 1])
    
    print(dp[n])

    λŒ“κΈ€

Designed by Tistory.