📌  相关文章
📜  在没有相邻对角线元素的情况下从顶部到底部找到最大和

📅  最后修改于: 2021-04-29 16:58:22             🧑  作者: Mango

给定N * M的矩阵A [] [] ,任务是在从每一行中选择一个没有相邻对角线元素的元素后,从顶行到底行找到最大和。

例子:

说明:如果要选择任何元素(如果我们选择了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