📍 백준 1904번 - 01타일문제 C++ [다이나믹 프로그래밍 알고리즘]
🧩문제 요약
<다이나믹 프로그래밍 알고리즘>
1, 00인 타일이 있다고 할 때,
n이 주어지면 n개의 타일을 이용해 만들 수 있는 모든 가짓수를 구하라.
대신 %15746의 나머지를 return 할것.
🧾내가 작성한 초기 코드
#include <iostream>
using namespace std;
int arr[1000001];
int solve(int n ){
if(n==1){
return 1;
}
if(n==2){
return 2;
}
if(arr[n] != 0){
return arr[n];
}
else{
arr[n] = solve(n-1) + solve(n-2);
return arr[n];
}
}
int main(){
int n ;
cin >> n ;
cout << solve(n)%15746 << "\n";
}
👍이 문제에서 배운점
처음에 재귀로 호출할 때 어떤 연관이 있는지 찾아내기 힘들었다.
그런데 결국 n이 주저였을 때 n으로 만들 수 있는 타일은 1 + (n-1), 00 + (n-2)라는 규칙을 찾았다.
하지만 자꾸 정답이 아니어서 뭐가 문제인지 조금 헤맸다.
😕 문제점 1.
long long타입으로도 커버되지 않는 큰 숫자.
✅ %15746
이 문제는 재귀함수를 만들고 DP로 풀이를 진행하는 것이 중요한 문제이지만 타입도 고려를 해봐야 한다.
재귀 함수를 작성하다 보면 피보나치 수열을 따른 다는 것을 알 수 있다.
n의 최대는 1000000이다. 그래서 피보나치 수열의 값이 매우 커질 수 있다. 이렇게 되면 long long타입으로도 감당할 수 없게 된다.
그래서 문제에서는 %15746을 하여 값을 return 하게 하고 있는데 이것을 잘 이해하지 못해서 계속 틀린답이 나온것이였다.
이는 최종 답을 모듈러 값으로 요구하는 것이고 경우의 수가 너무 크면 마지막에만 %연산을 해주는 것이 아니라 계산 과정에서도 계속 %해줘야 한다.
안그러면 중간에 오버플로우가 발생하게 된다.
🧾 완성된 코드
#include <iostream>
using namespace std;
int arr[1000001];
int solve(int n ){
if(n==1){
return 1;
}
if(n==2){
return 2;
}
if(arr[n] != 0){
return arr[n];
}
else{
arr[n] = (solve(n-1) + solve(n-2))%15746;
return arr[n];
}
}
int main(){
int n ;
cin >> n ;
cout << solve(n)%15746 << "\n";
}
'하루 알고리즘 1문제 풀기' 카테고리의 다른 글
백준 11866번 - 요세푸스 0 문제 C++ [Queue] (0) | 2025.04.09 |
---|---|
백준 2839번 - 설탕배달 문제 C++ [그리디 알고리즘/다이나믹 프로그래밍] (0) | 2025.04.08 |
백준 11399번 - ATM 문제 C++ [그리디 알고리즘] (0) | 2025.04.07 |
백준 2164번 - 카드2 문제 C++ [Queue] (0) | 2025.04.04 |
백준 10816번 - 숫자 카드2 문제 C++ [이진 탐색], upper_bound()/lower_bound() (0) | 2025.04.04 |