동적 계획법 문제입니다. 먼저 각 지역의 가치를
: 를 방문한 후 를 방문하여 얻을 수 있는 가치의 최댓값 : 을 방문한 후 를 방문하여 얻을 수 있는 가치의 최댓값 : 을 방문한 후 를 방문하여 얻을 수 있는 가치의 최댓값
한 마디로 정리하자면 어느 방향에서
점화식을 세웁시다.
마찬가지로
점화식이 나왔으니 이제 초기값을 구합시다.
재귀함수와 메모이제이션으로 구현한다면 문제 없지만 반복문으로 구현할 땐 순서가
매우 중요합니다.
#include<cstdio>
#include<algorithm>
#define INF 1000000000;
using namespace std;
int n, m;
int val[1000][1000];
int up[1000][1000], left[1000][1000], right[1000][1000];
int main(void) {
scanf("%d %d", &n, &m);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
scanf("%d", &val[i][j]);
left[0][0] = up[0][0] = val[0][0];
for (int j = 1; j < m; j++)
up[0][j] = -INF;
for (int j = 1; j < m; j++)
left[0][j] = left[0][j-1] + val[0][j];
for (int j = m-1; j >= 0; j--)
right[0][j] = -INF;
for (int i = 1; i < n; i++) {
for (int j = 0; j < m; j++)
up[i][j] = max({up[i-1][j], left[i-1][j], right[i-1][j]}) + val[i][j];
left[i][0] = -INF;
for (int j = 1; j < m; j++)
left[i][j] = max(up[i][j-1], left[i][j-1]) + val[i][j];
right[i][m-1] = -INF;
for (int j = m-2; j >= 0; j--)
right[i][j] = max(up[i][j+1], right[i][j+1]) + val[i][j];
}
printf("%d", max(left[n-1][m-1], up[n-1][m-1]));
return 0;
}