К вашему сведению, у нового издания книги есть ответ, но он настолько расплывчатый, что я не знаю, к чему это приведет.
В любом случае, я бы использовал «разделяй и властвуй» + динамическое программированиечтобы решить это.Определим MaxSum (x, y) как максимальную сумму любого подмассива внутри прямоугольника, ограниченного самым верхним левым углом массива NXN, с высотой y и шириной x.(поэтому ответ на вопрос будет в MaxSum (n-1, n-1))
MaxSum(x, y) is the max between:
1) MaxSum(x, y-1)
2) MaxSum(x-1, y)
3) Array[x, y] (the number in this N X N array for this specific location)
4) MaxEnding(x, y-1) + SUM of all elements from Array[MaxEndingXStart(x, y-1), y] to Array[x, y]
5) MaxEnding(x-1, y) + SUM of all elements from Array[x, MaxEndingYStart(x-1, y)] to Array[x, y]
MaxEnding (x, y-1) - максимальная сумма любого подмассива, который ВКЛЮЧАЕТ # вМассив [x, y-1].Аналогично, MaxEnding (x-1, y) - это максимальная сумма любого подмассива, который ВКЛЮЧАЕТ # в массиве [x-1, y].MaxEndingXStart (x, y-1) - это НАЧАЛЬНАЯ координата x подмассива, который имеет максимальную сумму любого подмассива, включающего # в массив [x, y-1].MaxEndingYStart (x-1, y) - это начальная координата y подмассива, который имеет максимальную сумму любого подмассива, включающего # в массив [x-1, y].
2 сумма в # 4и # 5 ниже можно легко вычислить, сохраняя сумму всех элементов, встречающихся в определенной строке, по мере прохождения каждого столбца, а затем вычитая 2 суммы, чтобы получить сумму для определенного раздела.
Для реализации этого, вам нужно будет сделать восходящий подход, так как вам нужно вычислить Max (x, y-1), Max (x-1, y), MaxEnding (x, y-1) и MaxEnding (x-1), у) .. так что вы можете делать поиск при вычислении MaxEnding (х, у).
//first do some preprocessing and store Max(0, i) for all i from 0 to n-1.
//and store Max(i, 0) for all i from 0 to n-1.
for(int i =1; i < n; i++){
for(int j=1; j < n; j++) {
//LOGIC HERE
}
}