코딩테스트/Lv1

[Python] 백준 온라인 저지 2293번

ggulgood 2022. 4. 27. 03:51

실버 1  https://www.acmicpc.net/problem/2293

 

2293번: 동전 1

첫째 줄에 n, k가 주어진다. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) 다음 n개의 줄에는 각각의 동전의 가치가 주어진다. 동전의 가치는 100,000보다 작거나 같은 자연수이다.

www.acmicpc.net

 

 

n가지 종류의 동전이 있다. 각각의 동전이 나타내는 가치는 다르다.

이 동전을 적당히 사용해서, 그 가치의 합이 k원이 되도록 하고 싶다. 그 경우의 수를 구하시오.

각각의 동전은 몇 개라도 사용할 수 있다.

사용한 동전의 구성이 같은데, 순서만 다른 것은 같은 경우이다.

 

 

 

[Python]

 

풀이 방법:

 

동적 계획법(Dynamic Programming, DP) 문제

  • '전체의 문제'를 '부분 문제'로 잘 나누었는가? 그렇다면 전체 문제를 해결하기 위한 부분 문제의 점화식은 무엇인가?
  • 부분 문제들을 해결하며 얻는 결과 값을 메모제이션 하는지
  • 부분 문제의 점화식은 부분 문제들 사이의 관계를 빠짐없이 고려하는지

 

  • 전체의 문제: 가치의 합이 k원이 되는 경우의 수
  • 부분 문제:
    • 가치의 합이 i (1 <= i <= k)원이 되는 경우의 수
    • 특정 동전을 썼을 때 가치의 합이 i원이 되는 경우의 수
  • 입출력 예시로 다른 예시를 생각해보며 테스팅 해볼 것
  • 각각의 숫자를 (1, 2, 5) 더해 숫자를 나타내는 방법을 나타낸 표
  • dp[ j ]에 dp[ j  -  i ]의 총 개수를 쭉 더해주면 된다

 

  dp[0] dp[1] dp[2] dp[3] dp[4] dp[5] dp[6]
i = 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)
i = 2     2
개수(1)
1 + 2
개수(1)
1 + 1 + 2
2 + 2
개수(2)
1 + 1 + 1 + 2
1 + 2 + 2
개수(2)
1 + 1 + 1 + 1 + 2
1 + 1 + 2 + 2
2 + 2 + 2
개수(3)
i = 5           5
개수(1)
5 + 1
개수(1)

 

 

코드:

import time
import sys
sys.stdin = open("input.txt", "r")
# input = sys.stdin.readline
start_time = time.time()

# source code

n, k = map(int, input().split())
c = [int(input()) for i in range(n)] # 코인의 종류
dp = [0 for i in range(k+1)] # 사이즈 k+1만큼의 리스트 선언
dp[0] = 1 # 인덱스0은 동전을 1개만 쓸 때의 경우의 수를 고려하기 위해 선언

for i in c:
    for j in range(1, k + 1):
        if j - i >= 0:
            dp[j] += dp[j - i]

print(dp[k])

#

end_time = time.time()
print("WorkingTime: {} sec".format(end_time-start_time))

 

 

 

 

추가 예정 - [Javascript]

풀이 방법:

정답: