알고리즘 분류별로 순서를 맞추는 건 포기했다. 차라리 나중에 글이 늘어나면 알고리즘 별로 시리즈를 따로 만들어야겠다.
n X m
크기의 금광이 있습니다. 금광은 1 X 1
크기의 칸으로 나누어져 있으며, 각 칸은 특정한 크기의 금이 들어 있습니다. 채굴자는 첫 번째 열부터 출발하여 금을 캐기 시작합니다. 맨 처음에는 첫번째 열의 어느 행에서든 출발할 수 있습니다. 이후에 m번에 걸쳐서 매번 오른쪽 위, 오른쪽, 오른쪽 아래 3가지 중에서 하나의 위치로 이동해야 합니다. 결과적으로 채굴자가 얻을 수 있는 금의 최대 크기를 출력하는 프로그램을 작성하세요.
만약 다음과 같이 3 X 4
크기의 금광이 존재한다고 가정합시다.
1 | 3 | 3 | 2 |
2 | 1 | 4 | 1 |
0 | 6 | 4 | 7 |
가장 왼쪽 위의 위치를(1, 1)
, 가장 오른쪽 아래 위치를 (n, m)
이라고 할 때, 위 예시에서는 (2, 1)
-> (3, 2)
-> (3, 3)
-(3, 4)
의 위치로 이동하면 총 19만큼의 금을 채굴할 수 있으며, 이때의 값이 최댓값입니다.
n X m
개의 위치에 매장된 금의 개수가 공백으로 구분되어 입력됩니다. (1 ≤ 각 위치에 매장된 금의 개수 ≤ 100)그 DP 문제가 책 뒤에 나오더라
dp[i][j] = max(dp[i, j-1], dp[i-1, j-1], dp[i+1, j-1]) + arr[i][j]
를 해주었다.i-1
이 존재하지 않고 마지막 행은 i+1
이 존재하지 않았다.실제로 사용하진 않아서 메모리를 좀 더 쓸 분이다.
20 X 20으로 꽉 채워서 주지 않는 한 문제가 생기진 않는다. 그 말은 꽉 채워서 주면 문제가 생긴다는 말이지..ㅎ
n
까지 인지 n-1
까지 인지 조금 고민하긴 했다. 머리가 슝슝 안 돌아가서 그렇다.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int arr[22][20];
int dp[22][20];
int main() {
int testCase;
cin >> testCase;
for (int i = 0; i < testCase; i++){
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < m; j++) {
scanf_s("%d", &arr[i][j]);
}
}
for (int i = 1; i <= n; i++){
dp[i][0] = arr[i][0];
}
for (int j = 1; j < m; j++) {
for (int i = 1; i <= n; i++) {
dp[i][j] = max(max(dp[i + 1][j - 1], dp[i][j - 1]), dp[i - 1][j - 1]) + arr[i][j];
}
}
int maxValue = 0;
for (int i = 1; i <= n; i++){
maxValue = max(maxValue, dp[i][m - 1]);
}
cout << maxValue << endl;
}
}