1학년

bird.j·2021년 8월 24일
0

백준

목록 보기
43/76

백준 5557

숫자가 주어졌을 때, 상근이가 만들 수 있는 올바른 등식의 수를 구하기.

  • 상근이가 1학년 때, 덧셈, 뺄셈을 매우 좋아했다. 상근이는 숫자가 줄 지어있는 것을 보기만 하면, 마지막 두 숫자 사이에 '='을 넣고, 나머지 숫자 사이에는 '+' 또는 '-'를 넣어 등식을 만들며 놀고 있다.
  • 상근이는 올바른 등식을 만들려고 한다. 상근이는 아직 학교에서 음수를 배우지 않았고, 20을 넘는 수는 모른다. 따라서, 왼쪽부터 계산할 때, 중간에 나오는 수가 모두 0 이상 20 이하이어야 한다.
  • 첫째 줄에 숫자의 개수 N이 주어진다. (3 ≤ N ≤ 100) 둘째 줄에는 0 이상 9 이하의 정수 N개가 공백으로 구분해 주어진다.
  • 첫째 줄에 상근이가 만들 수 있는 올바른 등식의 개수를 출력한다. 이 값은 263-1 이하이다.

입출력

입력출력
11
8 3 2 4 8 7 2 4 0 8 8
10
40
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1
7069052760


접근 방식

: 재귀호출로 푼다. --> 시간초과

알게된 점

DP로 풀기.

  • dp[i][j] = 경우의 수.
    • i까지의 원소를 사용하여 j가 나올 수 있는 모든 경우의 수.
    • i는 1부터 n-2까지. j는 0부터 21까지.
    • 조건에 맞을 때만 경우의 수 ++
  • dp[n-2]nums[-1]]이 구하고자 하는 값.

dp..역시 생각해내기 쉽지 않다..ㅠ



코드

DP

n = int(input())
nums = list(map(int, input().split()))
dp = [[0]*21 for _ in range(n)]

dp[0][nums[0]] = 1 # nums인덱스, nums 값
# i번째까지의 원소를 사용해서 j가 나올 수 있는 모든 경우의 수
for i in range(1, n-1): # nums의 수만큼
    for j in range(21): # 연산 결과 
        if dp[i-1][j] != 0: #이전 경우의 수
            if j + nums[i] <= 20:
                dp[i][j+nums[i]] += dp[i-1][j]
            if j - nums[i] >= 0:
                dp[i][j-nums[i]] += dp[i-1][j]
    
print(dp[n-2][nums[-1]])

재귀(시간초과)

import sys

def dfs(idx, result):
    global cnt
    if idx == n-1 :
        if result == nums[-1]:
            cnt += 1
            return
        else:
            return

    tmp = result + nums[idx]
    if 0<=tmp<=20:
        dfs(idx+1, tmp)

    tmp = result - nums[idx]
    if 0<=tmp<=20:
        dfs(idx+1, tmp)


n = int(sys.stdin.readline())
nums = list(map(int, sys.stdin.readline().split()))
cnt = 0
dfs(1, nums[0])
print(cnt)

0개의 댓글

관련 채용 정보