문제

오른쪽 그림과 같이 삼각형이 나선 모양으로 놓여져 있다. 첫 삼각형은 정삼각형으로 변의 길이는 1이다. 그 다음에는 다음과 같은 과정으로 정삼각형을 계속 추가한다. 나선에서 가장 긴 변의 길이를 k라 했을 때, 그 변에 길이가 k인 정삼각형을 추가한다.
파도반 수열 P(N)은 나선에 있는 정삼각형의 변의 길이이다. P(1)부터 P(10)까지 첫 10개 숫자는 1, 1, 1, 2, 2, 3, 4, 5, 7, 9이다.
N이 주어졌을 때, P(N)을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, N이 주어진다. (1 ≤ N ≤ 100)
출력
각 테스트 케이스마다 P(N)을 출력한다.
예제 입력 1
2 6 12
예제 출력 1
3 16
출처
ICPC > Regionals > Asia Pacific > Korea > Asia Regional - Daejeon 2013 G번
알고리즘 분류
- 수학
- 다이나믹 프로그래밍
문제 출처
https://www.acmicpc.net/problem/9461
9461번: 파도반 수열
오른쪽 그림과 같이 삼각형이 나선 모양으로 놓여져 있다. 첫 삼각형은 정삼각형으로 변의 길이는 1이다. 그 다음에는 다음과 같은 과정으로 정삼각형을 계속 추가한다. 나선에서 가장 긴 변의
www.acmicpc.net
문제 해결 방법
점화식 구하기

- 문제에서 주어진 그림을 통해 도출되는 값을 분석하면 다음과 같다.
N | 출력값(P(N)) |
1 | 1 |
2 | 1 |
3 | 1 |
4 | 2 |
5 | 2 |
6 | P(5) + P(1) = 3 |
7 | P(6) + P(2) = 4 |
8 | P(7) + P(3) = 5 |
9 | P(8) + P(4) = 7 |
10 | P(9) + P(5) = 9 |
- 일 경우, 다음과 같이 점화식을 구할 수 있다.
점화식을 토대로 구현하기
- 부터 점화식이 성립하므로, DP 테이블에서 범위는 문제에서 주어진 수(
1
,1
,1
,2
,2
)로 채운다.
// P(N) = P(N - 1) + P(N - 5) (N >= 6) ULL Calc(int n) { dp[1] = dp[2] = dp[3] = 1; dp[4] = dp[5] = 2; for (int i = 6; i <= n; i++) { dp[i] = dp[i - 1] + dp[i - 5]; } return dp[n]; }
N = 100
일 경우,888855064897
의 큰 수가 출력된다. 따라서 DP 테이블의 자료형을unsigned long long
으로 선언하하여 DP 테이블에 큰 수가 담길 수 있도록 하였다.
using ULL = unsigned long long; vector<ULL> dp; void Input() { cin >> N; dp.resize(N + 1); }
정확하게 풀기
- 파도반 수열의 정확한 점화식은 이다.
- 이 점화식을 토대로 코드를 작성하면 다음과 같다.
// P(1) = P(2) = P(3) = 1 (N < 4) // P(N) = P(N - 2) + P(N - 3) (N >= 4) ULL Calc(int n) { dp[1] = dp[2] = dp[3] = 1; for (int i = 4; i <= n; i++) { dp[i] = dp[i - 2] + dp[i - 3]; } return dp[n]; }
코드
#include <iostream> #include <vector> using namespace std; using ULL = unsigned long long; int T, N; vector<ULL> dp; void Input() { cin >> N; dp.resize(N + 1); } // P(N) = P(N - 1) + P(N - 5) (N >= 6) ULL Calc(int n) { dp[1] = dp[2] = dp[3] = 1; dp[4] = dp[5] = 2; for (int i = 6; i <= n; i++) { dp[i] = dp[i - 1] + dp[i - 5]; } return dp[n]; } void Output() { cout << Calc(N) << '\n'; dp.empty(); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> T; for (int i = 0; i < T; i++) { Input(); Output(); } return 0; }
채점 결과

참고
- [단계별로 풀어보기] > [동적 계획법 1]
- 실버III
파도반 수열(Padovan Sequence)

점화식()
- 의 경우 점화식은 다음과 같다.
- 의 경우 점화식은 다음과 같다.
참고 사이트
Padovan sequence - Wikipedia
From Wikipedia, the free encyclopedia Jump to navigation Jump to search Sequence of integers In number theory, the Padovan sequence is the sequence of integers P(n) defined[1] by the initial values P ( 0 ) = P ( 1 ) = P ( 2 ) = 1 , {\displaystyle P(0)=P(1)
en.wikipedia.org
'Problem Solving > BOJ' 카테고리의 다른 글
[BOJ-1932][C++] 정수 삼각형 (0) | 2022.12.08 |
---|---|
[BOJ-1149][C++] RGB거리 (0) | 2022.12.08 |
[BOJ-11652][C++] 카드 (0) | 2022.12.07 |
[BOJ-1912][C++] 연속합 (0) | 2022.12.07 |
[BOJ-1904][C++] 01타일 (0) | 2022.12.07 |
[BOJ-9184][C++] 신나는 함수 실행 (0) | 2022.12.04 |
[BOJ-24416][C++] 알고리즘 수업 - 피보나치 수 1 (0) | 2022.12.01 |
[BOJ-14889][C++] 스타트와 링크 (0) | 2022.12.01 |