바닥 공사
가로의 길이가 N, 세로의 길이가 2인 바닥을 덮개로 모두 덮는 경우의 수 구하는 문제이다. 덮개의 가지수는 총 3개이고 아래와 같다.
- 1 X 2
- 2 X 1
- 2 X 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
"""
입력조건 : 첫째 줄에 N이 주어진다.
출력조건 : 첫째줄에 2XN 크기의 바닥을 채우는 방법의 수를 796,796으로 나눈 나머지 출력
=> 결과값이 매우 커질 수 있기 때문에 특정한 수로 나눈 나머지를 취하게 하는 것임
"""
n = int(input())
d = [0]*1001
d[1] = 1
d[2] = 3
for i in range(3, n+1):
d[i] = (d[i-1] + 2*d[i-2])%796796
print(d[n])
효율적인 화폐구성
n개의 종류의 화폐가 있을 때, 이 화폐들의 개수를 최소한으로 용해서 그 가치의 합이 m원이 되도록하려 한다.
n=3, m=7이고 각 화폐 단위가 2,3,5인 경우를 가정해본다.
우선 각 인덱스에 해당하는 값으로 무한대의 값을 설정한다. 무한대의 값은 화폐가치 m이 10000원을 넘길수 없다는 점에서 착안해서 10001로 설정한다. 0원은 아무 화폐도 사용하지 않으면 그 자체로 달성이 가능하기 때문에 값을 0으로 처리한다.
인덱스 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
값 | 0 | 10001 | 10001 | 10001 | 10001 | 10001 | 10001 | 10001 |
이제 작은 화폐 단위부터 순서대로 반복해서 확인한다. 우선 2원 부터 시작하면, 2원을 만들기 위해서는 2원짜리 하나면되고 4원은 2원짜리 두개, 6원은 2원짜리 세개이기 때문에 아래와 같이 리스트가 갱신된다.
인덱스 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
값 | 0 | 10001 | 1 | 10001 | 2 | 10001 | 3 | 10001 |
두번째 화폐단위인 3을 확인하면, 3원을 만들기위해 3원짜리 하나가 필요하고 5원을 만들기 위해서는 2원과 3원 하나씩 필요하고 6원을 만들기 위해서는 3원짜리 두개가 필요하고 7원을 만들기 위해서는 2원짜리 두개와 3원짜리 하나가 필요하다.
인덱스 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
값 | 0 | 10001 | 1 | 1 | 2 | 2 | 2 | 3 |
마지막으로 5원도 적용하면 최종적으로 아래와같은 리스트가 만들어진다.
인덱스 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
값 | 0 | 10001 | 1 | 1 | 2 | 1 | 2 | 2 |
여기서 생각해보면, 7원을 만드는경우 5원을 적용하기 전에는 3인데 5원을 사용하면 2가된다. 이는 d[7]에서 5만큼 앞에 있는 인덱스인 2의 값인 1에다가 5원 한번만 더해주면 이전값과 비교해서 더 작은 값을 사용하기 때문에 이를 활용하면 점화식을 만들 수 있다. 그렇게 만들어진 최종 코드는 아래와 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
"""
입력조건 : 첫째 줄에 n, m. 이후 n개의 줄에는 각 화폐의 가치 입력(단, 10000원 이하)
출력조건 : 첫째줄에 m원을 만들기 위한 최소한의 화폐개수 출력. 불가능할 땐 -1 출력
"""
n, m = map(int, input().split())
arr = []
for i in range(n):
arr.append(int(input()))
d = [10001] * (m+1)
d[0] = 0
for i in range(n):
for j in range(arr[i], m+1):
if d[j-arr[i] != 10001: # i-k원을 만드는 방법이 존재하는 경우
d[j] = min(d[j], d[j - arr[i]] + 1)
if d[m] == 10001:
print(-1)
else:
print(d[m])