BOJ 11048 - 이동하기 문제풀이
문제를 읽고 이해하기
준규는 N×M 크기의 미로에 갇혀있다. 미로는 1×1크기의 방으로 나누어져 있고, 각 방에는 사탕이 놓여져 있다. 미로의 가장 왼쪽 윗 방은 (1, 1)이고, 가장 오른쪽 아랫 방은 (N, M)이다.
준규는 현재 (1, 1)에 있고, (N, M)으로 이동하려고 한다. 준규가 (r, c)에 있으면, (r+1, c), (r, c+1), (r+1, c+1)로 이동할 수 있고, 각 방을 방문할 때마다 방에 놓여져있는 사탕을 모두 가져갈 수 있다. 또, 미로 밖으로 나갈 수는 없다.
준규가 (N, M)으로 이동할 때, 가져올 수 있는 사탕 개수의 최댓값을 구하시오.
입력
첫째 줄에 미로의 크기 N, M이 주어진다. (1 ≤ N, M ≤ 1,000)
둘째 줄부터 N개 줄에는 총 M개의 숫자가 주어지며, r번째 줄의 c번째 수는 (r, c)에 놓여져 있는 사탕의 개수이다. 사탕의 개수는 0보다 크거나 같고, 100보다 작거나 같다.
출력
첫째 줄에 준규가 (N, M)으로 이동할 때, 가져올 수 있는 사탕 개수를 출력한다.
재정의와 추상화
동적계획법(DP)로 문제를 풀 수 있다. DFS로 문제를 풀 수 있지 않을까 잠시 생각했지만, DFS 원리를 생각하며 머릿속으로 1분 정도 생각해보면 안되는 이유를 알게 될 것이다. 점화식은 아래와 같다.
dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + candy[i][j]
- dp[i][j] : (i, j)까지 도달할 때까지 모은 사탕의 총합
- candy[i][j] : (i, j) 위치에 있는 방에 있는 사탕의 개수
코드 작성
#include <iostream>
using namespace std;
int main() {
cin.sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int arr[1001][1001];
int dp[1001][1001];
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
cin >> arr[i][j];
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
dp[i][j] = max(max(dp[i - 1][j - 1], dp[i - 1][j]), dp[i][j - 1]) + arr[i][j];
}
cout << dp[n][m];
return 0;
}
'알고리즘 > 문제풀이' 카테고리의 다른 글
BOJ 1920 - 수 찾기 문제풀이 (0) | 2020.04.01 |
---|---|
BOJ 11055 - 가장 큰 증가 부분 수열 (0) | 2020.04.01 |
BOJ 11052 - 카드 구매하기 문제풀이 (0) | 2020.04.01 |
BOJ 11057 - 오르막 수 문제풀이 (0) | 2020.03.31 |
BOJ 17839 - Baba is Rabbit 문제풀이 (0) | 2020.03.31 |
댓글
이 글 공유하기
다른 글
-
BOJ 1920 - 수 찾기 문제풀이
BOJ 1920 - 수 찾기 문제풀이
2020.04.01 -
BOJ 11055 - 가장 큰 증가 부분 수열
BOJ 11055 - 가장 큰 증가 부분 수열
2020.04.01 -
BOJ 11052 - 카드 구매하기 문제풀이
BOJ 11052 - 카드 구매하기 문제풀이
2020.04.01 -
BOJ 11057 - 오르막 수 문제풀이
BOJ 11057 - 오르막 수 문제풀이
2020.03.31