Разбор
Пусть — исходная таблица. Обозначим через максимальную сумму чисел на пути от любой клетки первой строки до клетки . Тогда
Для корректного вычисления значений в первом и последнем столбцах положим
Инициализируем первую строку массива значениями первой строки таблицы :
Ответом на задачу будет максимальное значение в последней (-ой) строке массива .
Пример
Рассмотрим входной тест.
Реализация алгоритма
Объявим константу для хранения минимального значения, а также массивы и .
#define MAX 202 #define MIN -2000000000 int a[MAX][MAX], dp[MAX][MAX];
Читаем входные данные. Верхний левый угол таблицы будем хранить в . Столбцы с номерами и в массиве заполним минимально возможным значением .
scanf("%d %d", &n, &m); for (i = 1; i <= n; i++) { dp[i][0] = dp[i][m + 1] = MIN; for (j = 1; j <= m; j++) scanf("%d", &a[i][j]); }
Скопируем первую строку массива в массив .
for (i = 1; i <= n; i++) dp[1][i] = a[1][i];
Пересчитаем максимальные суммы на путях от верхней строки до клетки и сохраним их в массиве .
for (i = 2; i <= n; i++) for (j = 1; j <= m; j++) dp[i][j] = max(max(dp[i - 1][j - 1], dp[i - 1][j]), dp[i - 1][j + 1]) + a[i][j];
Найдем наибольшее число в последней (-ой) строке массива .
res = MIN; for (i = 1; i <= m; i++) if (dp[n][i] > res) res = dp[n][i];
Выводим ответ.
printf("%d\n", res);
Java реализация
import java.util.*; public class Main { static int a[][], dp[][]; final static int MIN = -2000000000; public static void main(String[] args) { Scanner con = new Scanner(System.in); int n = con.nextInt(); int m = con.nextInt(); dp = new int[n+1][m+2]; a = new int[n+1][m+2]; for (int i = 1; i <= n; i++) { dp[i][0] = dp[i][m + 1] = MIN; for (int j = 1; j <= m; j++) a[i][j] = con.nextInt();; } for (int i = 1; i <= m; i++) dp[1][i] = a[1][i]; for (int i = 2; i <= n; i++) for (int j = 1; j <= m; j++) dp[i][j] = Math.max(Math.max(dp[i - 1][j - 1], dp[i - 1][j]), dp[i - 1][j + 1]) + a[i][j]; int res = MIN; for (int i = 1; i <= m; i++) if (dp[n][i] > res) res = dp[n][i]; System.out.println(res); con.close(); } }