给定N * M的矩阵A [] [] ,任务是在从每一行中选择一个没有相邻对角线元素的元素后,从顶行到底行找到最大和。
例子:
Input: A = { {1, 2, 3, 4}, {8, 7, 6, 5}, {10, 11, 12, 13} }
Output: 25
Explanation:
Selected elements to give maximum sum –
Row 0 = 4
Row 1 = 8
Row 2 = 13
Sum = 25
Input: A = { {1, 6}, {5, 3}, {11, 7} }
Output: 17
Explanation:
Selected elements to give maximum sum –
Row 0 = 1
Row 1 = 5
Row 2 = 11
说明:如果要选择任何元素(如果我们选择了A [i] [j]),则无法选择元素A [i + 1] [j + 1]和A [i + 1] [j-1]。
在给定示例中,在这种情况下,从顶部行选择最大元素,其中最大为4,则无法选择元素A [1] [2],即元素6,从可用选项中选择元素最大的元素8。同样,不能从第三行中选择元素11。选择元素13以获取最大总和为25。
天真的方法:从每行中选择1个元素后,生成N个元素的所有组合,然后选择产生最大和的组合。
高效的方法:想法是以自下而上的方式使用动态编程的概念。从给定矩阵的最底行开始,然后重复以下过程,直到到达最顶行为止。
- 创建最底部行元素的辅助数组及其对应的索引。
- 排序辅助数组。
- 遍历辅助数组,并为每个元素从上一行中找到要添加到当前元素的最大元素,以产生最大和,从而对于每个A [i] [j]而言,所选元素不是A [i-1] [ j + 1]或A [i-1] [j-1] 。
- 重复此操作,直到到达给定矩阵数组的最上一行。
- 从第一行中找到最大元素以获取最大总和
下面是上述方法的实现。
C++
// C++ implementation to find
// maximum sum from top to bottom
// row with no adjacent diagonal elements
#include
using namespace std;
// Function to find the maximum
// path sum from top to bottom row
int maxSum(vector >& V,
int n, int m){
int ans = 0;
for (int i = n - 2; i >= 0; --i) {
// Create an auxiliary array of next row
// with the element and it's position
vector > aux;
for (int j = 0; j < m; ++j) {
aux.push_back({ V[i + 1][j],
j });
}
// Sort the auxiliary array
sort(aux.begin(), aux.end());
reverse(aux.begin(), aux.end());
// Find maximum from row above to
// be added to the current element
for (int j = 0; j < m; ++j) {
// Find the maximum element from
// the next row that can be added
// to current row element
for (int k = 0; k < m; ++k) {
if (aux[k].second - j == 0 ||
abs(aux[k].second - j) > 1) {
V[i][j] += aux[k].first;
break;
}
}
}
}
// Find the maximum sum
for (int i = 0; i < m; ++i) {
ans = max(ans, V[0][i]);
}
return ans;
}
// Driver Code
int main()
{
vector > V{{ 1, 2, 3, 4 },
{ 8, 7, 6, 5 },
{ 10, 11, 12, 13 }};
int n = V.size();
int m = V[0].size();
// Function to find maximum path
cout << maxSum(V, n, m);
return 0;
}
Java
// Java implementation to find maximum
// sum from top to bottom row with no
// adjacent diagonal elements
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG{
// Function to find the maximum
// path sum from top to bottom row
static int maxSum(int[][] V,
int n, int m)
{
int ans = 0;
for(int i = n - 2; i >= 0; --i)
{
// Create an auxiliary array of next row
// with the element and it's position
ArrayList aux = new ArrayList<>();
for(int j = 0; j < m; ++j)
{
aux.add(new int[]{V[i + 1][j], j});
}
// Sort the auxiliary array
Collections.sort(aux, (a, b) -> b[0] - a[0]);
// Find maximum from row above to
// be added to the current element
for(int j = 0; j < m; ++j)
{
// Find the maximum element from
// the next row that can be added
// to current row element
for(int k = 0; k < m; ++k)
{
if (aux.get(k)[1] - j == 0 ||
Math.abs(aux.get(k)[1] - j) > 1)
{
V[i][j] += aux.get(k)[0];
break;
}
}
}
}
// Find the maximum sum
for(int i = 0; i < m; ++i)
{
ans = Math.max(ans, V[0][i]);
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int[][] V = { { 1, 2, 3, 4 },
{ 8, 7, 6, 5 },
{ 10, 11, 12, 13 } };
int n = V.length;
int m = V[0].length;
// Function to find maximum path
System.out.println(maxSum(V, n, m));
}
}
// This code is contributed by offbeat
Python3
# Python3 implementation to find
# maximum sum from top to bottom
# row with no adjacent diagonal elements
# Function to find the maximum
# path sum from top to bottom row
def maxSum(V, n, m):
ans = 0
for i in range(n - 2, -1, -1):
# Create an auxiliary array of next row
# with the element and it's position
aux = []
for j in range(m):
aux.append([V[i + 1][j], j])
# Sort the auxiliary array
aux = sorted(aux)
aux = aux[::-1]
# Find maximum from row above to
# be added to the current element
for j in range(m):
# Find the maximum element from
# the next row that can be added
# to current row element
for k in range(m):
if (aux[k][1] - j == 0 or
abs(aux[k][1] - j) > 1):
V[i][j] += aux[k][0]
break
# Find the maximum sum
for i in range(m):
ans = max(ans, V[0][i])
return ans
# Driver Code
if __name__ == '__main__':
V=[[ 1, 2, 3, 4 ],
[ 8, 7, 6, 5 ],
[ 10, 11, 12, 13]]
n = len(V)
m = len(V[0])
# Function to find maximum path
print(maxSum(V, n, m))
# This code is contributed by mohit kumar 29
C#
// C# implementation to find
// maximum sum from top to bottom
// row with no adjacent diagonal elements
using System;
using System.Collections.Generic;
class GFG {
// Function to find the maximum
// path sum from top to bottom row
static int maxSum(int[,] V, int n, int m){
int ans = 0;
for (int i = n - 2; i >= 0; --i) {
// Create an auxiliary array of next row
// with the element and it's position
List> aux = new List>();
for (int j = 0; j < m; ++j) {
aux.Add(new Tuple(V[i + 1, j], j));
}
// Sort the auxiliary array
aux.Sort();
aux.Reverse();
// Find maximum from row above to
// be added to the current element
for (int j = 0; j < m; ++j) {
// Find the maximum element from
// the next row that can be added
// to current row element
for (int k = 0; k < m; ++k) {
if (aux[k].Item2 - j == 0 ||
Math.Abs(aux[k].Item2 - j) > 1) {
V[i, j] += aux[k].Item1;
break;
}
}
}
}
// Find the maximum sum
for (int i = 0; i < m; ++i) {
ans = Math.Max(ans, V[0,i]);
}
return ans;
}
// Driver code
static void Main()
{
int[,] V = {{ 1, 2, 3, 4 },
{ 8, 7, 6, 5 },
{ 10, 11, 12, 13 }};
int n = V.GetLength(0);
int m = V.GetLength(1);
// Function to find maximum path
Console.WriteLine(maxSum(V, n, m));
}
}
// This code is contributed by divyesh072019.
25