백준 2293 동전 1 (DP)

맹민재·2023년 4월 11일
0

알고리즘

목록 보기
54/134

처음 시도 방법

n, k =[int(v) for v in input().split()]
coins = [0] * n
dp = [[0] * (k+1) for _ in range(n)]

for i in range(n):
    coins[i] = int(input())

for i in range(len(coins)):
    for j in range(1, k+1):
        if j == coins[i]:
            dp[i][j] = dp[i-1][j] + 1
        elif j > coins[i]:
            dp[i][j] = dp[i-1][j] + dp[i][j- coins[i]]
        else:
            dp[i][j] = dp[i-1][j]

print(dp[-1][-1])

냅색 알고리즘을 통해 시도했다.
dp를 2차원 List로 만들고 행은 coin의 개수 열은 0~K까지의 금액이다.
2중 for 문을 돌면서 j 값이 현재 동전의 가치랑 같으면 이전 Dp 값에 + 1
현재 동전의 가치보다 크다면 이전 Dp 값에 현재 행의 J - coin의 DP 값을 더해준다.
그렇지 않은 경우 즉 coin의 가치보다 작은 값은 이전 DP 값을 그대로 저장한다.

이렇게 구하면 답은 맞을 수 있지만 문제에서 주어지는 메모리는 고작 4MB이다. 이럴 시 리스트는 약 1,000,000의 int형 데이터를 저장할 수 있다.

현재 문제를 생각 했을 때 최대 list 필요 양은 n k(100 10,000)로
여유가 없다. 실제로 돌려보면 메모리 초과가 나온다.

그래서 아래와 같이 1차원 List Dp로 문제를 해결해야한다.

n, k =[int(v) for v in input().split()]
coins = [0] * n
dp = [0] * (k+1)

for i in range(n):
    coins[i] = int(input())

dp[0] = 1

for coin in coins:
    for j in range(coin, k+1):
        if j >= coin:
            dp[j] = dp[j] + dp[j - coin]

print(dp[-1])

개념 자체는 똑같다 j 값이 현재 동전의 가치보다 크다면 이전 Dp 값에 현재 행의 J - coin의 DP 값을 더해준다.
하지만 1차원 리스트로 하기 때문에 이전 Dp 값이 현재 인덱스에 이미 저장 되어있다.


전혀 생각지도 못한 효율적인 방법이다...

profile
ㄱH ㅂrㄹ ㅈr

0개의 댓글