📜  最多可以从一行中选择 K 个元素时的最大路径和

📅  最后修改于: 2022-05-13 01:56:04.415000             🧑  作者: Mango

最多可以从一行中选择 K 个元素时的最大路径和

给定一个大小为N * M的矩阵mat [][] 和一个整数K ,任务是找到从左上角单元格(0, 0 ) 到右下角单元格 ( N–1, M–1 ) 的路径)的给定矩阵,使得:

  • 允许一次向右和向下移动。即,从(i,j)到(i,j-1)和(i+1,j)。
  • 路径中元素的总和最大,并且可以从一行中选择不超过 K 个单元格。

例子:

朴素方法:最简单的方法是找到从左上角到右下角的所有可能路径,并且单行中的单元格不超过K。计算它们之间的最大路径和。

时间复杂度: O( M+N-2 C N-1 )
辅助空间: O(1)

有效的方法:解决问题的有效方法是使用基于以下思想的动态规划

请按照以下步骤解决此问题

  • 声明一个 3D 数组(比如dp 大小为N * M * (K + 1)
  • 迭代给定的矩阵:
    • 以相反的顺序迭代l的所有可能值(从K-1 到 0 ):
      • 检查dp的当前状态是否为正值。
      • 然后更新第 (l + 1) 个状态的dp数组,因为我们包含了网格的当前值。
    • 再次遍历l的所有可能值:
      • 检查dp的当前状态是否为正值。
      • 然后更新当前单元格的向下单元格(如果存在)。
      • 如果存在,还更新当前单元格的右侧单元格。
  • 声明一个整数变量ans并将其初始化为 0。
  • 遍历l的所有可能值。
    • ans更新为自身的最大值和 dp[N-1][M-1][l]。
  • 最后,返回ans

以下是上述方法的实现:

C++
// C++ code to implement the approach
 
#include 
using namespace std;
 
// Function to find the maximum path sum
int maximumProfits(int n, int m, int k,
                   vector >& grid)
{
 
    // Declare a -d array named “dp”
    // with size ‘N’ * ‘M’ * (‘K’ + 1).
    int dp[n][m][k + 1];
 
    // Initialize the "dp" array with INT_MIN.
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            for (int l = 0; l < k + 1; l++) {
                dp[i][j][l] = INT_MIN;
            }
        }
    }
 
    // Base case.
    dp[0][0][0] = 0;
 
    // Iterate over the grid.
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
 
            // Iterate over the possible
            // values of ‘l’ in reverse order.
            for (int l = k - 1; l >= 0; l--) {
 
                // If the current state
                // of “dp” has positive value
                if (dp[i][j][l] >= 0) {
 
                    // Update “dp” array for
                    //(‘l’ + 1)-th state since
                    // we include
                    // the current value
                    // of the grid.
                    dp[i][j][l + 1]
                        = max(dp[i][j][l + 1],
                              dp[i][j][l]
                                  + grid[i][j]);
                }
            }
 
            // Again iterate over
            // all possible values of ‘l’.
            for (int l = 0; l < k + 1; l++) {
 
                // If the current state
                // of “dp” has positive value
                if (dp[i][j][l] >= 0) {
 
                    // Update the downward cell
                    // of the current cell
                    // if it exists.
                    if (i + 1 < n) {
                        dp[i + 1][j][0] = max(
                            dp[i + 1][j][0],
                            dp[i][j][l]);
                    }
 
                    // Update the right cell
                    // of the current cell
                    // if it exists.
                    if (j + 1 < m) {
                        dp[i][j + 1][l] = max(
                            dp[i][j + 1][l],
                            dp[i][j][l]);
                    }
                }
            }
        }
    }
 
    // Declare an integer variable “ans” and
    // initialize it with 0.
    int ans = 0;
 
    // Iterate over all possible values of l
    for (int l = 0; l < k + 1; l++) {
 
        // Update ans as max of itself and
        // the dp value for (n -1, m - 1)th
        // cell  for the current value of l
        ans = max(ans, dp[n - 1][m - 1][l]);
    }
 
    // Return the “ans”.
    return ans;
}
 
// Driver code
int main()
{
    int N = 3, M = 3, K = 2;
    vector > mat = { { 2, 10, 8 },
                                 { 8, 8, 8 },
                                 { 0, 1, 0 } };
    cout << maximumProfits(N, M, K, mat);
    return 0;
}


Java
// JAVA code to implement the approach
import java.util.*;
class GFG {
 
  // Function to find the maximum path sum
  public static int
    maximumProfits(int n, int m, int k,
                   ArrayList > grid)
  {
 
    // Declare a -d array named “dp”
    // with size ‘N’ * ‘M’ * (‘K’ + 1).
    int dp[][][] = new int[n][m][k + 1];
 
    // Initialize the "dp" array with INT_MIN.
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        for (int l = 0; l < k + 1; l++) {
          dp[i][j][l] = Integer.MIN_VALUE;
        }
      }
    }
 
    // Base case.
    dp[0][0][0] = 0;
 
    // Iterate over the grid.
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
 
        // Iterate over the possible
        // values of ‘l’ in reverse order.
        for (int l = k - 1; l >= 0; l--) {
 
          // If the current state
          // of “dp” has positive value
          if (dp[i][j][l] >= 0) {
 
            // Update “dp” array for
            //(‘l’ + 1)-th state since
            // we include
            // the current value
            // of the grid.
            dp[i][j][l + 1] = Math.max(
              dp[i][j][l + 1],
              dp[i][j][l]
              + grid.get(i).get(j));
          }
        }
 
        // Again iterate over
        // all possible values of ‘l’.
        for (int l = 0; l < k + 1; l++) {
 
          // If the current state
          // of “dp” has positive value
          if (dp[i][j][l] >= 0) {
 
            // Update the downward cell
            // of the current cell
            // if it exists.
            if (i + 1 < n) {
              dp[i + 1][j][0]
                = Math.max(dp[i + 1][j][0],
                           dp[i][j][l]);
            }
 
            // Update the right cell
            // of the current cell
            // if it exists.
            if (j + 1 < m) {
              dp[i][j + 1][l]
                = Math.max(dp[i][j + 1][l],
                           dp[i][j][l]);
            }
          }
        }
      }
    }
 
    // Declare an integer variable “ans” and
    // initialize it with 0.
    int ans = 0;
 
    // Iterate over all possible values of l
    for (int l = 0; l < k + 1; l++) {
 
      // Update ans as max of itself and
      // the dp value for (n -1, m - 1)th
      // cell  for the current value of l
      ans = Math.max(ans, dp[n - 1][m - 1][l]);
    }
 
    // Return the “ans”.
    return ans;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int N = 3, M = 3, K = 2;
    ArrayList > mat
      = new ArrayList >();
    ArrayList temp1 = new ArrayList(
      Arrays.asList(2, 10, 8));
    ArrayList temp2 = new ArrayList(
      Arrays.asList(8, 8, 8));
    ArrayList temp3 = new ArrayList(
      Arrays.asList(0, 1, 0));
    mat.add(temp1);
    mat.add(temp2);
    mat.add(temp3);
    System.out.print(maximumProfits(N, M, K, mat));
  }
}
 
// This code is contributed by Taranpreet


Python3
# Python code to implement the approach
import sys
 
INT_MIN = -sys.maxsize - 1
 
# Function to find the maximum path sum
def maximumProfits(n, m, k,grid):
 
    global INT_MIN
 
    # Declare a -d array named “dp”
    # with size ‘N’ * ‘M’ * (‘K’ + 1).
    # Initialize the "dp" array with INT_MIN.
    dp = [[[INT_MIN for i in range(k + 1)] for j in range(m)] for l in range(n)]
 
    # Base case.
    dp[0][0][0] = 0
 
    # Iterate over the grid.
    for i in range(n):
        for j in range(m):
 
            # Iterate over the possible
            # values of ‘l’ in reverse order.
            for l in range(k - 1,-1,-1):
 
                # If the current state
                # of “dp” has positive value
                if (dp[i][j][l] >= 0):
 
                    # Update “dp” array for
                    #(‘l’ + 1)-th state since
                    # we include
                    # the current value
                    # of the grid.
                    dp[i][j][l + 1] = max(dp[i][j][l + 1],dp[i][j][l] + grid[i][j])
 
            # Again iterate over
            # all possible values of ‘l’.
            for l in range(k + 1):
 
                # If the current state
                # of “dp” has positive value
                if (dp[i][j][l] >= 0):
 
                    # Update the downward cell
                    # of the current cell
                    # if it exists.
                    if (i + 1 < n):
                        dp[i + 1][j][0] = max(dp[i + 1][j][0],dp[i][j][l])
 
                    # Update the right cell
                    # of the current cell
                    # if it exists.
                    if (j + 1 < m):
                        dp[i][j + 1][l] = max(dp[i][j + 1][l],dp[i][j][l])
 
    # Declare an integer variable “ans” and
    # initialize it with 0.
    ans = 0
 
    # Iterate over all possible values of l
    for l in range(k + 1):
 
        # Update ans as max of itself and
        # the dp value for (n -1, m - 1)th
        # cell  for the current value of l
        ans = max(ans, dp[n - 1][m - 1][l])
 
    # Return the “ans”.
    return ans
 
# Driver code
N, M, K = 3, 3, 2
mat = [ [ 2, 10, 8 ],[ 8, 8, 8 ],[ 0, 1, 0 ] ]
print(maximumProfits(N, M, K, mat))
 
# This code is contributed by shinjanpatra.


C#
// C# code to implement the approach
using System;
using System.Collections.Generic;
public class GFG{
 
  // Function to find the maximum path sum
  static int
    maximumProfits(int n, int m, int k,
                   List > grid)
  {
 
    // Declare a -d array named “dp”
    // with size ‘N’ * ‘M’ * (‘K’ + 1).
    int[, ,] dp = new int[n,m,k + 1];
 
    // Initialize the "dp" array with INT_MIN.
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        for (int l = 0; l < k + 1; l++) {
          dp[i, j, l] = Int32.MinValue;
        }
      }
    }
 
    // Base case.
    dp[0,0,0] = 0;
 
    // Iterate over the grid.
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
 
        // Iterate over the possible
        // values of ‘l’ in reverse order.
        for (int l = k - 1; l >= 0; l--) {
 
          // If the current state
          // of “dp” has positive value
          if (dp[i,j,l] >= 0) {
 
            // Update “dp” array for
            //(‘l’ + 1)-th state since
            // we include
            // the current value
            // of the grid.
            dp[i, j,l+1] = Math.Max(
              dp[i, j,l+1],
              dp[i, j,l]
              + grid[i][j]);
          }
        }
 
        // Again iterate over
        // all possible values of ‘l’.
        for (int l = 0; l < k + 1; l++) {
 
          // If the current state
          // of “dp” has positive value
          if (dp[i,j,l] >= 0) {
 
            // Update the downward cell
            // of the current cell
            // if it exists.
            if (i + 1 < n) {
              dp[i + 1,j,0]
                = Math.Max(dp[i + 1,j,0],
                           dp[i,j,l]);
            }
 
            // Update the right cell
            // of the current cell
            // if it exists.
            if (j + 1 < m) {
              dp[i,j + 1,l]
                = Math.Max(dp[i,j + 1,l],
                           dp[i,j, l]);
            }
          }
        }
      }
    }
 
    // Declare an integer variable “ans” and
    // initialize it with 0.
    int ans = 0;
 
    // Iterate over all possible values of l
    for (int l = 0; l < k + 1; l++) {
 
      // Update ans as max of itself and
      // the dp value for (n -1, m - 1)th
      // cell  for the current value of l
      ans = Math.Max(ans, dp[n - 1,m - 1,l]);
    }
 
    // Return the “ans”.
    return ans;
  }
 
  // Driver code
  static public void Main (){
 
    int N = 3, M = 3, K = 2;
    List> mat = new List>();
    mat.Add(new List {2, 10, 8 });
    mat.Add(new List { 8, 8, 8 });
    mat.Add(new List { 0, 1, 0 });
 
    Console.Write(maximumProfits(N, M, K, mat));
  }
}
 
// This code is contributed by hrithikgarg03188.


Javascript


输出
28

时间复杂度: O (N * M * K)
辅助空间: O(N * M * K)