본문 바로가기

다이나믹 프로그래밍

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

같은 수를 연속해서 쓰면 안된다. -> 점화식이 이차원 배열로 나옴

d[i][j] = d[i - 1][2] + d[i-1][3] + d[i - 2][1] + d[i-2][3] + d[i - 3][1] + d[i-1][2]

 

테스트 케이스마다 dp를 구하면 시간 초과가 난다!!

케이스가 크다! overlflow가 무조건 난다..

dp와 오버플로우 -> 항상 조심

테스트 케이스마다 나머지 연산을 해줘야한다

오버플로우 방지 나머지 연산

(a + b) % c = (a % c + b % c) % c      [곱셈에서도 성립]

(a / b) % c = (a * b ^ (c - 2)) % c   

(a - b) % c = (a % c - b % c + c) % c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>
long long d[1000001][4];
const long long mod = 1000000009LL;
const int limit = 100000;
int main() {
    for (int i=1; i<=limit; i++) {
        if (i-1 >= 0) {
            d[i][1= d[i-1][2+ d[i-1][3];
            if (i == 1) {
                d[i][1= 1;
            }
        }
        if (i-2 >= 0) {
            d[i][2= d[i-2][1+ d[i-2][3];
            if (i == 2) {
                d[i][2= 1;
            }
        }
        if (i-3 >= 0) {
            d[i][3= d[i-3][1+ d[i-3][2];
            if (i == 3) {
                d[i][3= 1;
            }
        }
        d[i][1] %= mod;
        d[i][2] %= mod;
        d[i][3] %= mod;
    }
    int t;
    scanf("%d",&t);
    while (t--) {
        int n;
        scanf("%d",&n);
        printf("%lld\n",(d[n][1+ d[n][2+ d[n][3])%mod);
    }
}
cs

 

'다이나믹 프로그래밍' 카테고리의 다른 글

가장 긴 증가하는 부분 수열  (0) 2023.03.26
쉬운 계단 수 & 이친수  (0) 2023.03.23
카드 구매하기 2  (0) 2023.03.22
카드 구매하기 (최대값)  (0) 2023.03.02
1, 2, 3 더하기  (0) 2023.03.02