ν‹°μŠ€ν† λ¦¬ λ·°

728x90
λ°˜μ‘ν˜•

문제

 

5557번: 1ν•™λ…„

상근이가 1ν•™λ…„ λ•Œ, λ§μ…ˆ, λΊ„μ…ˆμ„ 맀우 μ’‹μ•„ν–ˆλ‹€. μƒκ·Όμ΄λŠ” μˆ«μžκ°€ 쀄 μ§€μ–΄μžˆλŠ” 것을 보기만 ν•˜λ©΄, λ§ˆμ§€λ§‰ 두 숫자 사이에 '='을 λ„£κ³ , λ‚˜λ¨Έμ§€ 숫자 μ‚¬μ΄μ—λŠ” '+' λ˜λŠ” '-'λ₯Ό λ„£μ–΄ 등식을 λ§Œλ“€λ©° 놀��

www.acmicpc.net

 

문제 풀이

 μˆ«μžκ°€ μ£Όμ–΄ 질 λ•Œ, +, - λ₯Ό 톡해 숫자λ₯Ό 계산 ν•  수 있으며 κ³„μ‚°λœ 숫자의 λ²”μœ„λŠ” 0 보닀 크고, 20 보닀 μž‘μ•„μ•Ό ν•œλ‹€. λ˜ν•œ 주어진 숫자λ₯Ό 계산할 λ•Œ, λ§ˆμ§€λ§‰μœΌλ‘œ 주어진 μˆ«μžμ™€ μΌμΉ˜ν•΄μ•Ό ν•œλ‹€. 예제 μž…λ ₯1의 경우 문제의 주어진 νžŒνŠΈμ™€ 같이 λ‹€μŒκ³Ό 같은 경우의 μˆ˜κ°€ μžˆλ‹€.

 

  • 8+3-2-4+8-7-2-4-0+8=8
  • 8+3-2-4+8-7-2-4+0+8=8
  • 8+3+2+4-8-7+2-4-0+8=8
  • 8+3+2+4-8-7+2-4+0+8=8
  • 8+3+2-4+8-7+2+4-0-8=8
  • 8+3+2-4+8-7+2+4+0-8=8
  • 8-3+2+4-8+7+2+4-0-8=8
  • 8-3+2+4-8+7+2+4+0-8=8
  • 8-3+2-4+8+7+2-4-0-8=8
  • 8-3+2-4+8+7+2-4+0-8=8

 μ΄ 경우의 μˆ˜λŠ” DFSλ₯Ό 톡해 ꡬ할 μˆ˜λ„ μžˆμ§€λ§Œ, 2차원 배열을 μ΄μš©ν•˜μ—¬ DP둜 ν’€μˆ˜λ„ μžˆλ‹€. 이와 같은 λ¬Έμ œλŠ” 이전에 닀룬

κΈ°νƒ€λ¦¬μŠ€νŠΈμ™€ μœ μ‚¬ν•œ λ°©μ‹μœΌλ‘œ ν’€λ©΄ λœλ‹€. λ‹€λ§Œ λ‹€λ₯Έ 점이 μžˆλ‹€λ©΄ 예제 μž…λ ₯ 1의 경우 8μ΄λΌλŠ” 값이 λ‚˜μ˜€λŠ” 횟수λ₯Ό 좜λ ₯ν•΄μ•Ό ν•œλ‹€. λ”°λΌμ„œ λͺ¨λ“  숫자λ₯Ό μ‚¬μš©ν•˜μ—¬ κ³„μ‚°ν•˜μ˜€μ„ λ•Œ, 8이 λ˜λŠ” κ²½μš°κ°€ λͺ‡ κ°œμΈμ§€ μ€‘μ²©ν•˜λ©΄μ„œ 체크해야 ν•œλ‹€.

 

'''
7 
8 3 2 4 8 7 2 
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
[0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0] 
[0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0] 
[0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] 
[0, 0, 1, 0, 1, 0, 1, 0, 2, 0, 2, 0, 2, 0, 0, 0, 1, 0, 1, 0, 1]
'''

 μ˜ˆλ₯Ό λ“€μ–΄ μœ„μ™€ 같은 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ₯Ό μ‹€ν–‰ν•œλ‹€λ©΄, 2차원 배열에 λ‚˜νƒ€λ‚Ό 수 μžˆλŠ” μˆ«μžλ“€μ΄ ν‘œμ‹œλ  것이고, 2κ°€ λ˜λŠ” 경우의 μˆ˜λŠ” 1κ°œλΌλŠ” 것을 μ•Œ 수 μžˆλ‹€. λ§Œμ•½ 8, 10, 12κ°€ λœλ‹€λ©΄ 2κ°€μ§€μ˜ 경우의 수 κ°€ μžˆλ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€. 이와 같이 νŠΈλ¦¬μ™€ 같은 ꡬ쑰둜 탐색이 λœλ‹€λ©΄ DFSλ₯Ό 톡해 풀지 μ•Šκ³  2차원 배열을 μ‚¬μš©ν•˜μ—¬ 정닡을 찾을 수 μžˆλ‹€.

 

μ½”λ“œ

from sys import stdin


if __name__ == "__main__":
    n = int(stdin.readline())
    nums = list(map(int, stdin.readline().split()))
    dp = [[0] * 21 for _ in range(n - 1)]
    dp[0][nums[0]] = 1

    for i in range(1, n - 1):
        cur_num = nums[i]

        for j in range(21):
            if not dp[i - 1][j]:
                continue

            if j + cur_num <= 20:
                dp[i][j + cur_num] += dp[i - 1][j]

            if 0 <= j - cur_num:
                dp[i][j - cur_num] += dp[i - 1][j]

    print(dp[-1][nums[-1]])
728x90
λ°˜μ‘ν˜•
λŒ“κΈ€
κΈ€ 보관함
μ΅œκ·Όμ— 올라온 κΈ€
μ΅œκ·Όμ— 달린 λŒ“κΈ€