给定一个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不能从第3行选择。选择元素 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.
Javascript
25
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live