DP(Dynamic Programming)
하나의 큰 문제를 작은 문제로 나누어 해결하는 기법
동적프로그래밍을 사용하는 대표적인 문제가 피보나치 수열이다.
f(n) = f(n - 1) + f(n - 2) (n > 2), f(0) = 0, f(1) = 1
위의 수열을 해결하기 위해 재귀적으로 문제를 해결할 수도 있지만 중복 실행이 발생하게 되고 n이 커지면 커질수록 비효율적이다.
따라서 f(0), f(1)을 배열에 저장해서 한번 구한 값을 또 구하지 않도록 아래와 같이 f(n)을 구할 때까지 반복적으로 연산을 진행한다.
DP를 사용해서 문제를 풀기 위해서는 문제를 작은 문제로 나누고 이 결과를 이용해서 동일한 작은 문제를 해결하도록 해서 소문제를 재사용해야한다.
즉, 비슷한 여러 개의 소문제로 나눌 수 있어야하며, 소문제의 결과가 다른 소문제를 푸는 열쇠로 작용할 수 있어야한다.
class Solution {
public int tribonacci(int n) {
int[] arr = new int[n + 3];
arr[0] = 0;
arr[1] = 1;
arr[2] = 1;
if (n > 2) {
for(int i = 3; i <= n; i++) {
arr[i] = arr[i - 3] + arr[i - 2] + arr[i - 1];
}
}
return arr[n];
}
}
top-left에서 down-right에 있는 로봇을 만나러 가야하는데 경로가 몇 개가 있는지에 대한 문제
down과 left만을 반복하고 있고 가고자 하는 위치까지의 도달 경로 개수 = 이전 위치까지의 도달 경로 개수 합(위 + 왼쪽 경로 개수)
초기값은 오른쪽으로만 갔을 경우, 아래로만 갔을 경우 각 경로는 1개라고 세팅했다.
class Solution {
public int uniquePaths(int m, int n) {
int[][] grid = new int[m][n];
// 초기값 세팅
for(int i = 0; i < m; i++) {
grid[i][0] = 1;
}
for(int i = 0; i < n; i++) {
grid[0][i] = 1;
}
for(int i = 1; i < m; i++) {
for(int j = 1; j < n; j++) {
grid[i][j] = grid[i - 1][j] + grid[i][j - 1];
}
}
return grid[m - 1][n - 1];
}
}
'코딩테스트' 카테고리의 다른 글
[leetcode] 338. Counting Bits (0) | 2024.06.03 |
---|---|
[leetcode] 746. Min Cost Climbing Stairs (0) | 2024.06.03 |
[leetcode] 374. Guess Number Higher or Lower (0) | 2024.05.31 |
[leetcode] 17. Letter Combinations of a Phone Number (0) | 2024.05.28 |
[leetcode] 215. Kth Largest Element in an Array (0) | 2024.05.28 |