개발기록장

[알고리즘] DP유형 - 백준 9095번 파이썬 본문

TIL/알고리즘 with 파이썬

[알고리즘] DP유형 - 백준 9095번 파이썬

yangahh 2021. 1. 5. 20:14

www.acmicpc.net/problem/9095

 

9095번: 1, 2, 3 더하기

각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 출력한다.

www.acmicpc.net

 

문제

정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 7가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다.

  • 1+1+1+1
  • 1+1+2
  • 1+2+1
  • 2+1+1
  • 2+2
  • 1+3
  • 3+1

정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.

 

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다. n은 양수이며 11보다 작다.

 

출력

각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 출력한다.

 

예제 입력

3 4 7 10

 

예제 출력

7 44 274

 

풀이

기본적인 다이나믹프로그래밍(DP)유형이다.

 

어떤 수 i를 1과 2, 3의 합으로 표현할 수 있는 방법을 생각해보면, 다음과 같이 3가지 경우를 생각해 볼 수 있다.

 

경우1) i - 3 에 3을 더하는 경우

경우2) i - 2 에 2를 더하는 경우

경우3) i - 1 에 1을 더하는 경우

 

즉, i-3까지의 1, 2, 3의 합으로 나타내는 방법의 수와 i-2까지의 방법의 수, i-1까지의 방법의 수를 모두 더해주면 i까지의 방법의 수가 된다.

 

이 아이디어를 토대로 d[i]를 1, 2, 3의 합을 이용하여 어떤 수 i를 만들기 위한 방법의 수라고 할때, 점화식을 세워보면 아래와 같다.

d[\i] = d[i - 3] + d[i - 2] + d[i - 1] (단, d[1]=1, d[2]=2, d[3]=3)

 

코드

# 테스트 케이스 입력받기
T = int(input())

# 입력받은 테스트 케이스 수 만큼 반복
for _ in range(T):
	
    n = int(input())
	
    
    # DP 테이블 초기화
    d = [0] * 12  # n이 최대 11미만이기 때문에

    d[1] = 1
    d[2] = 2
    d[3] = 4
	
    
 	# 보텀업 방식으로 구현
    for i in range(4, 12):
        d[i] = d[i - 1] + d[i - 2] + d[i - 3]


    print(d[n])