[BOJ][⚪2][백준#15990] 1, 2, 3 더하기 5
작성:    
업데이트:
카테고리: BOJ Silver II
태그: BOJ, BOJ Silver, PS, Python
문제 출처
문제
정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 3가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다. 단, 같은 수를 두 번 이상 연속해서 사용하면 안 된다.
1+2+1 1+3 3+1
정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다. n은 양수이며 100,000보다 작거나 같다.
출력
각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 1,000,000,009로 나눈 나머지를 출력한다.
예제
입력
3
4
7
10
출력
3
9
27
My Sol
import sys
input = sys.stdin.readline
sys.setrecursionlimit(100000)
def main(n):
global memo
if memo[0][n]: return memo[0][n]
if not memo[0][n-1]:
main(n-1)
check123(n)
calc0(n)
return memo[0][n]
def check123(n):
global memo
d = {
1: [2, 3],
2: [1, 3],
3: [1, 2]
}
for i in range(1, 4):
for j in d[i]:
memo[i][n] += memo[j][n-i]
memo[i][n] = memo[i][n]%1000000009
def calc0(n):
global memo
memo[0][n] = (memo[1][n] + memo[2][n] + memo[3][n]) % 1000000009
memo = [[0]*1000001 for _ in range(4)]
memo[1][1] = memo[2][2] = memo[3][3] = 1
calc0(1)
calc0(2)
T = int(input())
for _ in range(T):
n = int(input())
print(main(n))
DP를 사용하는 문제였다.
접근방식
- 4행 10만열의 메모이제이션 2차원 배열 memo를 만든다.
- n열의 1행의 값은 n-2열 2행의 값과 n-3열 3행의 값을 더한 것이다.
- 즉, 각 행은 행의 수를 더해서 현재 n을 만드는 경우이다.
- 직전에 같은 수를 더했으면 배제해야 하므로 1, 2, 3 중 지금 행이 아닌 것만 더한다.
- 이 더한 값이 1000000009보다 크다면 나머지를 넣어준다.
- n열의 1, 2, 3행의 값을 모두 더한 것을 0행에 넣어준다.
- 만약 구하는 수가 n일 때 memo[0][n]이 있다면 그대로 출력해준다.
- 없다면 main(n-1)을 실행해 memo[0][n-1]까지 만들어준다.
- 이는 즉 memo[i][n-1]을 다 채우는 것이기 때문에 memo[i][n]을 채울 수 있다.
- 이를 채우는 check123 함수를 만들어 채워준다.
주의해야 할 점은 1, 2, 3은 각각 자신 자체가 1이기 때문에 이에 대해 초기화 해주어야 한다는 점이다.
결과
맞았습니다!!
모범답안
import sys
n = int(input())
x = [4]
for _ in range(n):
x.append(int(sys.stdin.readline()))
maxs = max(x) + 1
a1 = [0] * maxs
a2 = [0] * maxs
a3 = [0] * maxs
a1[1] = a2[2] = a1[3] = a2[3] = a3[3] = 1
for i in range(4, maxs):
a1[i] = (a2[i-1]%1000000009 + a3[i-1]%1000000009)
a2[i] = (a1[i-2]%1000000009 + a3[i-2]%1000000009)
a3[i] = (a1[i-3]%1000000009 + a2[i-3]%1000000009)
for i in x[1:]:
tem = a1[i] + a2[i] + a3[i]
print(tem % 1000000009)
메모리 사용이 적고, 연산 시간과 코드가 짧은 풀이를 분석해보려 한다.
그런데 의외다. 생각보다 별 게 없다. 그냥 처음에 냅다 dp 배열을 만들어 주고 시작한다. 2차원 배열을 만든 것이 아니라 1차원 배열 3개를 만들었고, 하드코딩해서 각각의 값을 만들어주었다.
단순한 코드인데 이렇게 좋은 성능을 내는지 알 수 없다.
댓글남기기