2020. 8. 24. 22:58ㆍ알고리즘/Baekjoon
DP(Dynamic Programming) - 동적 프로그래밍
데이터 값들을 배열에 저장해 필요할 경우 빼서 사용할 수 있는 알고리즘
피보나치 때 썼던 재귀함수와 비슷하지만 트리가 하위 Degree로 내려가면서
이미 했던 연산을 중복 연산하지 않고 점화식 배열에 저장해 둔 값을 꺼내어 쓴다.
따라서 시간 복잡도가 줄어들며 메모리를 적게 쓸 수 있다는 장점이 있다.
문제 풀이
접근방식인 동적 프로그래밍을 처음 봤고 방식을 도출하지 못해 나동빈 알고리즘 강의 유튜브를 참고했다.
그럼에도 점화식 이해를 못하여 황진경코딩영재학원 채널에서 동일한 올림피아드 문제를 설명해주신 영상을
보고 난 뒤에 완전히 이해할 수 있었다.
점화식은 dp[n] = dp[n-1] + dp[n-2] 이다.
주어진 타일 형태는 1x2, 2x1 두 가지 타일이고 채워야할 타일 크기는 2xn으로 세로 길이가 고정이다.
우선 n이 1, 2, 3, 4, 5...일 때를 직접 그림 그려본다. n = 5로 가정했을 때 패턴을 도출할 수 있는데,
소유한 타일 유형이 2개 뿐이기 때문에 경우의 수는 n = 4(5-1)일 때 2x1 타일을 각각 경우의 수에 추가한 값.
그리고 n = 3(5-2)일 때 1x2 타일을 각각 경우의 수에 추가한 값.
위의 두 가지 밖에 없다. 그 밖에 경우의 수는 n = 4 나 n = 3의 경우의 수에 포함되기 때문에 구하지 않아도 된다.
n = 2 에 2x1 타일을 추가한 값은 n = 3 경우의 수에 포함되기 때문이다.
그래서 코드를 짜보면 두 가지로 방법으로 풀 수 있다. 차이점은 메서드를 활용하냐 마냐인데 뭘 잘못했는진 몰라도
메서드를 사용하면 백준 제출 시 시간초과라고 자꾸 떠서 for문을 이용해 메서드 없이 바로 출력하는 방식을 택했다.
1) for문 이용한 메서드 없이 바로 출력한 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Tiling_2xn_11726 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int num = Integer.parseInt(br.readLine());
int[] dp = new int[num+1];
dp[1] = 1;
dp[2] = 2;
//dp 알고리즘
for(int i = 3; i <= num; i++) {
if(dp[i] != 0) {
dp[i] = dp[i];
} else {
//dp[num] = dp(n-1)함수로 설정해줘야만 재귀함수가 실행된다. 배열로 잡아주면 메서드가 실행되지 않기 때문에 제자리 값 0만 출력한다.
dp[i] = (dp[i - 1] + dp[i - 2]) % 10007;
}
}
//출력
System.out.println(dp[num]);
}
}
2) 메서드 만들어 출력한 코드
import java.io.IOException;
import java.io.InputStreamReader;
public class Tiling_2xn_11726 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int num = Integer.parseInt(br.readLine());
//출력
System.out.println(dp[num]);
}
public static int dp(int num) {
int[] dp = new int[num+1];
if(num == 1) return 1;
if(num == 2) return 2;
if(dp[num] != 0) {
return dp[num];
} else {
dp[num] = (dp(num-1) + dp(num-2)) % 10007;
return dp[num];
}
}
}
'알고리즘 > Baekjoon' 카테고리의 다른 글
[백준] 11654 - 아스키 코드 변환 (0) | 2020.09.02 |
---|---|
[백준] 1065 - 한수 (0) | 2020.09.01 |
[백준] 11399 - ATM (0) | 2020.08.26 |
[백준] 1003 - 피보나치 함수(재도전) (0) | 2020.08.26 |
[백준] 1758- 알바생 강호 (0) | 2020.08.26 |