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 |