[python/파이썬] 백준 15990 1, 2, 3 더하기 5
[문제 출처]
https://www.acmicpc.net/problem/15990
15990번: 1, 2, 3 더하기 5
각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 1,000,000,009로 나눈 나머지를 출력한다.
www.acmicpc.net
[문제 풀이]
9095번 문제인 '1, 2, 3 더하기'와 유사하지만 15990번 문제는 9095번과는 달리 2차원 배열을 사용하여 해결하는 문제이다.
1,2,3 이 세 가지의 숫자를 사용하되 연속적으로는 사용할 수 없다.
따라서 n에 대한 답을 알기 위해서는 n행 3열짜리 리스트가 필요하다.
기본적인 규칙은 간단하다.
dp[n][0]에는 n을 나타내는 방법중에 마지막 숫자가 1로 끝나는 경우의 수를 저장한다.
dp[n][1]에는 n을 나타내는 방법중에 마지막 숫자가 2로 끝나는 경우의 수를 저장한다.
dp[n][2]에는 n을 나타내는 방법중에 마지막 숫자가 3으로 끝나는 경우의 수를 저장한다.
연속적으로 같은 수를 사용할 수 없기 dp[n][0] 뒤에는 2 혹은 3을 배치한다.
같은 방식으로 dp[n][1] 뒤에는 1, 3
dp[n][2] 뒤에는 1,2만 올 수 있다.
이런 규칙을 사용하면
dp[n][0]은 1로 끝나야 하므로 n보다 1작은 수인 n-1의 dp값중에 2와 3으로 끝나는 경우의 합을 저장한다.
dp[n][1]은 2로 끝나야 하므로 n보다 2작은 수인 n-2의 dp값중에 1과 3으로 끝나는 경우의 합을 저장한다.
dp[n][2]은 3로 끝나야 하므로 n보다 3작은 수인 n-3의 dp값중에 1과 2로 끝나는 경우의 합을 저장한다.
결론은 이런 규칙을 따른다.
> dp[n][0] = dp[n-1][1] + dp[n-1][2]
> dp[n][1] = dp[n-2][2] + dp[n-2][0]
> dp[n][2] = dp[n-3][0] + dp[n-3][1]
그리고 n에 대한 경우의 수는 위의 세 값의 합이 된다.
import sys
input = sys.stdin.readline
T = int(input())
dp = [[0 for _ in range(3)] for i in range(100001)]
dp[1] = [1, 0, 0]
dp[2] = [0, 1, 0]
dp[3] = [1, 1, 1]
for i in range(4, 100001):
dp[i][0] = (dp[i-1][1] + dp[i-1][2])%1000000009
dp[i][1] = (dp[i-2][2] + dp[i-2][0])%1000000009
dp[i][2] = (dp[i-3][0] + dp[i-3][1])%1000000009
#나머지를 저장하지 않으면 값이 너무 커져 시간초과가 뜸
for j in range(T):
n = int(input())
print(sum(dp[n])%1000000009)
#마지막에도 나머지 연산을 해줘야 틀리지 않음
[유사한 문제]
아래의 문제를 풀어보지 않았다면 먼저 풀어보고 이번 문제를 풀면 좋을 것 같다.
https://www.acmicpc.net/problem/9095
9095번: 1, 2, 3 더하기
각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 출력한다.
www.acmicpc.net
[9095번 문제 풀이 링크]
https://sodehdt-ldkt.tistory.com/63
[python/파이썬] 백준 9095 1, 2, 3 더하기
문제 정수 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의 합으로 나타내..
sodehdt-ldkt.tistory.com