티스토리 뷰

백준 온라인 저지(BOJ) 1904번 01타일
https://www.acmicpc.net/problem/1904
1904번: 01타일
지원이에게 2진 수열을 가르쳐 주기 위해, 지원이 아버지는 그에게 타일들을 선물해주셨다. 그리고 이 각각의 타일들은 0 또는 1이 쓰여 있는 낱장의 타일들이다. 어느 날 짓궂은 동주가 지원이
www.acmicpc.net
* 사용언어 : C언어, C++
1. 문제
1 하나로 이루어진 타일 또는 0타일 두 개를 붙인 00타일로 만들 수 있는 크기가 N인 타일(2진 수열)의 개수를 출력
N은 최대 1,000,000이고, 출력은 수열의 개수를 15,746으로 나눈 나머지로 출력

2. 풀이
단순 재귀로 구현하면 시간 초과가 발생합니다.
동적 계획법에 속하는 문제인 만큼 dp[] 배열을 선언한 후 값을 저장하면서 풀어줍니다.
다만 이 문제는 00 또는 1 타일을 하나 씩 배치하면서 개수를 세는 백트래킹 방식으로 구현한다면,
dp 배열을 활용하더라도 시간 초과가 발생하게 됩니다.
정리해서 다시 말하면 top-down 방식으로는 풀 수 없는 문제입니다.
bottom-up 방식으로 문제를 풀기 위해서는 수열의 개수가 증가하는 규칙을 찾아야 합니다.
특별한 규칙이 보이지 않아서 1부터 5까지 가능한 모든 2진 수열을 직접 적어보며 규칙을 찾아보았습니다.

우선 N = 1이거나 2일 때는 특별한 규칙이 없습니다.
N = 3일 때를 보면 맨 앞 자리에 00 또는 1을 배치할 수 있는데
00을 배치한 경우 1자리(3 - 2)가 남기 때문에 N = 1일 때의 경우와 같고,
1을 배치한 경우 2자리(3 - 1)가 남기 때문에 N = 2일 때의 경우와 같아집니다.
여기서 규칙을 바로 찾을 수 있었습니다.
N = n일 때 가능한 모든 2진 수열의 개수는 [N = n - 2일 때의 개수] + [N = n - 1일 때의 개수]였습니다.
다시 말하면 피보나치 수열과 같은 방식으로 구현할 수 있다는 것을 확인할 수 있었습니다.
(단, 피보나치 수열은 N이 2일 때의 값도 1이므로 결과값은 다릅니다.)
추가로 나머지 연산(% 모듈러)을 미리 해주지 않으면 값이 매우 커져서 오답이 됩니다.
나머지 연산은 분배 법칙이 가능하기 때문에 dp 배열에 넣을 때 미리 나머지 연산을 하여 기록했습니다.
모듈러 연산을 매 번 하기 때문에 dp배열에 입력되는 최대값은 2^15보다 작아집니다.
따라서 dp 배열을 int가 아닌 short로 선언하여 메모리 사용량도 줄일 수 있었습니다. (5,016KB → 3,064KB)
3. 코드
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
/*
1904_01타일
3064KB 4ms
*/
#include <cstdio>
const int LM = 1e6 + 1;
const int BASE = 15746;
int N, cnt;
short dp[LM];
void tile(int n) {
dp[1] = 1, dp[2] = 2;
for (int i = 3; i <= n; ++i) dp[i] = (dp[i - 1] + dp[i - 2]) % BASE;
}
int main() {
#ifdef _WIN32
freopen("input.txt", "r", stdin);
#endif // _WIN32
scanf("%d", &N);
tile(N);
printf("%d\n", dp[N]);
return 0;
}
'개발자 > 문제풀이 (C언어)' 카테고리의 다른 글
[백준/BOJ] 1149번 RGB거리 (C/C++) (0) | 2024.02.28 |
---|---|
[백준/BOJ] 9461번 파도반 수열 (C/C++) (0) | 2024.02.26 |
[백준/BOJ] 9184번 신나는 함수 실행 (C/C++) (0) | 2024.02.24 |
[백준/BOJ] 24416번 알고리즘 수업 - 피보나치 수 1 (C/C++) (0) | 2024.02.24 |
[백준/BOJ] 14889번 스타트와 링크 (C/C++) (0) | 2024.02.22 |
- Total
- Today
- Yesterday
- 삼성전자
- 호암의마지막꿈
- 정올
- 센터독서클럽
- 동탄에듀센터2
- 독서감상평
- 나의첫죽음학수업
- 영화감상평
- JUNGOL
- 인간본성불패의법칙
- 당신도느리게나이들수있습니다
- 최재천의공부
- 쿠프마케팅
- 세상을 읽는 새로운 언어 빅데이터
- 유연함의힘
- 나는늘잘해야한다고생각한다
- AdSendse
- 문현공
- 긴 자리 덧셈 뺄셈
- 관계가상처가되기전에
- 자동차보험
- 독서 감상평
- 안전운전특약
- 정세현의통찰
- 시대예보
- 긴 자리 곱셈
- 자료구조
- 동탄에듀센터
- 알고리즘
- 여가포인트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |