-
[백준 15988]123 더하기 3알고리즘/Dynamic Programming 2019. 12. 16. 10:14
Type : Dynamic Programming
접근
- 재귀 탐색만으로는 시간 초과가 발생 하는 문제이다. 접근을 달리하여 완전 동적 계획법으로 문제를 풀어야 한다.
주요 포인트
함수의 배열화
- 함수의 배열화란 예상되는 함수의 결과값을 배열에 미리 저장해두어 계산해나가는 방식을 말한다.
- 주로 Bottom UP 방식에서 활용 된다.
- 이번 문제처럼 재귀트리가 무수히 많이 발생하는 경우에는 작은 값부터 배열을 채워나가는게 효율적이다.
- 100 만번 * 3 => 1초이내 해결가능
함수의 배열화 응용
- 1, 2, 3 더하기를 좀 더 깊이 생각해보면 숫자 n을 만드는 경우의 수는 갯수(n-1) + 갯수(n-2) + 갯수(n-3) 과 같다
- 1로 시작 하면서 n을 만드는 경우
- 2로 시작 하면서 n을 만드는 경우
- 3으로 시작하면서 n을 만드는 경우
- 재귀 호출에서 f(n+1) + f(n+2) + f(n+3) 과 같은 경우라 보면 된다.*
점화식 도출
- dp[n] = dp[n-1] + dp[n-2] + dp[n-3]
오버플로우 방지
- 문제에 주어진 대로 배열의 값은 항상 값의 나머지로 저장 한다
- 배열의 타입을 long long 으로 선언한다.
구현 코드
#include <iostream> #define mod 1000000009 #define LL long long #define MAX 1000001 using namespace std; LL arr[MAX]; //배열에 경우의 수를 저장, 최초 1회만 실행 void init(){ //배열값 초기화 arr[0] = 1; arr[1] = 1; arr[2] = 2; arr[3] = 4; //최대값 까지 경우의 수 저장 for(int i = 4 ; i <= MAX ; i++){ for(int j = 1 ; j<=3 ; j++){ arr[i] += arr[i-j]; } arr[i] = arr[i] % mod; } } int main(int argc, const char * argv[]) { int t,n; init(); cin>>t; //배열의 값을 출력 하기만 한다. for(int i = 0 ; i < t ; i++){ cin>>n; cout<<arr[n]<<endl; } return 0; }
깨달은 점
- 함수의 배열화를 통해 시간을 줄일 수 있다.
- 함수의 배열화에선 작은값부터 서서히 채워 나가는 Bottom up 방식을 사용한다.
- 기존의 값을 활용하는 방식
- (n+1)(x) (n-1)(o)
'알고리즘 > Dynamic Programming' 카테고리의 다른 글
백준_2163 초콜릿 자르기 (0) 2020.01.29 [백준 15989]1,2,3 더하기 4 (0) 2019.12.18 [백준 12101]123 더하기2 (0) 2019.12.16 [백준 9095]123 더하기 (0) 2019.12.13 [백준 2294] 동전 2 (0) 2019.12.10