일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 입/출력
- 엑셀
- 백준
- string 메소드
- 장고란
- k-eta
- 2557
- EOF
- 매크로
- 이분그래프
- Django란
- 시간복잡도
- Django의 편의성
- iOS14
- Django Nodejs 차이점
- string 함수
- scanf
- 구조체와 클래스의 공통점 및 차이점
- getline
- correlation coefficient
- 프레임워크와 라이브러리의 차이
- 자료구조
- double ended queue
- 입출력 패턴
- vscode
- c++
- 표준 입출력
- 연결요소
- 알고리즘 공부방법
- UI한글변경
- Today
- Total
Storage Gonie
챕터3-8. DP | 문제 풀이2 - (2) 백준 No.10844 : 쉬운 계단 수 본문
쉬운 계단 수 문제
- https://www.acmicpc.net/problem/10844
문제요약
정수 N이 주어지는데 인접한 자리의 수 차이가 모두 1인 수를 '계단 수' 라고 칭한다. ex) 45656
길이가 N인 계단 수의 개수를 구하고 1000000000로 나눈 나머지를 출력하라.
해결 방법
1. D[N] 에 어떤 값을 저장할 것인지 문장으로 정의해줘야 한다.
- D[N][L] = "L로 끝나는 길이가 N인 '계단 수' 의 개수"
- 이전 문제에서는 0 또는 1만 왔는데, 여기는 한 자리에 0~9가 올 수 있기 때문에 1차원으로 문제를 풀 수 없다.
따라서 2차원 배열을 활용하게 된다.
2. D[N]의 값을 어떻게하면 찾을 수 있을지 점화식을 생각한다.
- 정수 N이 주어지고, 앞에 어떤 조합이 존재하고 마지막 조합에서 아래와 같은 방법 중 1가지를 선택할 수 있다.
case 1) N번째 자리에 L이 올 때 N-1번째 자리에 L-1이 오는 경우
case 2) N번째 자리에 L이 올 때 N-1번째 자리에 L+1이 오는 경우
따라서, 점화식은 D[N][L] = D[N-1][L-1] + D[N-1][L+1] (1<=L<=8)이고,
L = 0 인 경우, D[N][0] = D[N-1][1] 이고,
L = 9 인 경우, D[N][9] = D[N-1][8] 이다.
3. 다이나믹 프로그래밍 방법을 적용할 수 있는 문제인지 확인 => 1, 2번을 거쳐야 이게 잘 보임.
- 위와 같이 큰 문제를 작은 문제로 쪼갤 수 있으며, 작은 문제도 큰 문제와 같은 방법으로 풀 수 있고, 작은 문제들이 겹친다.
(Overlapping SubProblem)
- 문제의 정답을 작은 문제의 정답으로부터 구할 수 있으며, 문제의 크기에 상관없이 어떤 한 문제의 정답은 일정하다.
(Optimal Substructure)
4. 코드구현
- 1000000000으로 나눈 나머지를 구하라는 유형의 문제이기 때문에 d 배열에 나머지를 저장해줘야 한다는 것을 주의하자.
또한, 마지막 출력할 전 d[n][0] ~ d[n][9] 를 모두 더하는데 이 더한 값 또한 1000000000 으로 나눠줘야 한다는 것을 명심하자.
<Top-down 방식>
2차원 배열을 사용하므로 Bottom-up 방식으로 쉽게 구하자.
<Bottom-up 방식>
(1) 구현
-> 'for문을 이용한 반복문'으로 구현
#include <iostream>
using namespace std;
int d[101][10];
int main()
{
int n;
cin >> n;
// n이 1일 때 결과가 9이므로 해주는 초기화
for (int i = 1; i <= 9; i++)
d[1][i] = 1;
// d 계산하기
for (int i = 2; i <= n; i++)
{
for(int j = 0; j <= 9; j++)
{
if (j == 0)
d[i][j] = d[i-1][j+1];
else if (j == 9)
d[i][j] = d[i-1][j-1];
else
d[i][j] = d[i-1][j-1] + d[i-1][j+1];
d[i][j] %= 1000000000;
}
}
// 구해진 d 합하여 출력하기
long long sum = 0;
for(int i = 0; i <= 9; i++)
sum += d[n][i];
cout << sum % 1000000000 << endl;
}
(2) 시간복잡도
= for 문의 반복 횟수
= 9 * N = O(N)
'알고리즘 > 알고리즘 기초(코드플러스)' 카테고리의 다른 글
챕터3-10. DP | 문제 풀이2 - (4) 백준 No.9465 : 스티커 (0) | 2019.05.09 |
---|---|
챕터3-9. DP | 문제 풀이2 - (3) 백준 No.11057 : 오르막 수 (0) | 2019.05.08 |
챕터3-7. DP | 문제 풀이2 - (1) 백준 No.2193 : 이친수 (0) | 2019.05.08 |
챕터3-6. DP | 문제 풀이1 - (5) 백준 No.11052 : 카드 구매하기 (0) | 2019.04.30 |
챕터3-5. DP | 문제 풀이1 - (4) 백준 No.9095 : 1, 2, 3 더하기 (0) | 2019.04.30 |