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
|
#include <iostream>
using namespace std;
// 라이의 블로그 DP #2
#define MAX 100
#define LL long long
LL dp[MAX][2]={0};
void binary(int N){
if(N<2){
dp[0][0] = 0;
dp[1][0] = 0;
dp[1][1] = 1;
} else{
binary(N-1);
dp[N][0] = dp[N-1][0]+dp[N-1][1];
dp[N][1] = dp[N-1][0];
}
}
int main(){
// 거꾸로 생각을 해서 dp[K][0]: K자리 이친수가 0으로 끝날 경우의 수는 K-1자리가 0으로 끝나는 경우와 K-1이 1로 끝나는 경우 합친거
// Long long 써주기!!
int N;
cin >> N;
binary(N);
cout << dp[N][0]+dp[N][1] << endl;
}
|
cs |
1. 0으로 끝날 경우엔 뒤에 0과 1이 올 수 있다.
2. 1로 끝날 경우엔 뒤에 0밖에 오지 못한다.
이 두가지의 원리를 발견하고, dp의 장점인 미리 구해놓은 값을 효율적으로 재사용을 할 줄 안다면 풀 수 있는 문제였다.
처음에 이 문제를 접근할 때, 엄청 구질구질(?)하게 dp를 사용해서 메모리 오류가 계속 떴다.
하지만 이 두가지의 원리를 거꾸로 생각해보자. 내가 구해야 하는 N번째 경우의 수는 0으로 끝나는 애들이랑 1로 끝나는 애들로 나뉠 수 있다. 0으로 끝나는 애들은 바로 이전의 애가 0으로 끝나거나 1로 끝난 경우를 합한 경우의 수고, 1로 끝나는 애들은 이전의 애가 0으로 끝난 경우의 수랑 똑같다. 그리고 마지막에 이 둘을 합쳐주기만 하면 된다.
그래서 dp[MAX][2]를 만들어주고, dp[N][0]엔 N번째 이친수가 0으로 끝나는 경우의 수, 즉 N-1번째 이친수가 0으로 끝나는 경우와 1로 끝나는 경우를 합쳐서 넣어주면 된다.
그리고 dp[N][1]엔 N번째 이친수가 1로 끝나는 경우의 수, 즉 N-1번째 이친수가 0으로 끝나는 경우를 넣어주면 된다.
'알고리즘 > 백준' 카테고리의 다른 글
백준 boj 21608. 상어초등학교 (0) | 2025.03.20 |
---|---|
백준 boj. 17142 연구소 3 [골드 🥇🥇🥇] (0) | 2025.03.10 |
백준 boj. 17484 진우의 달 여행 [실버 🥈🥈🥈] (0) | 2025.03.07 |
boj >> 1931 회의실 배정(c++) (0) | 2020.04.13 |
boj >> 17070 파이프 옮기기1 (0) | 2020.03.28 |