📌  相关文章
📜  通过最多弹出N个元素来最大化S个堆栈的最顶层元素的总和

📅  最后修改于: 2021-05-07 00:32:51             🧑  作者: Mango

给定S个长度为M的堆栈,任务是通过弹出最多N个元素来最大化每个堆栈顶部的元素总数。
例子:

方法:可以将此问题简化为0/1背包问题。要解决此问题,请按照以下步骤操作:

  1. 创建一个带有(S + 1)行和(N + 1)列的二维表dp [] [] 。在每个索引dp [i] [j]处,通过将j个元素弹出到第i堆栈来存储最大和。
  2. 将所有索引dp [] []初始化为0。
  3. 从i = 0到S – 1遍历每个堆栈
  4. 现在,对于i堆栈,通过弹出j(1到N)个元素来计算最大可能的和。
  5. 可以从已经访问过的所有i堆栈中选择这些j元素。因此,对于从0到min(j,堆栈大小)的所有k值, dp [i + 1] [j]存储最大的stacks [i] [k] + dp [i] [j-k] 。关系stacks [i] [k] + dp [i] [jk]表示通过从当前i堆栈中弹出k个元素而获得的和,以及通过从已经访问过的堆栈中弹出j-k个元素而可能得到的最大和。
  6. 对所有i堆栈完成一次后,找到[1,N – 1]范围内所有i的最大dp [S] [i ]
  7. 在上一步获得的最大值是必需的答案。

下面的代码是上述方法的实现:

C++
// C++ Program to maximize the 
// sum of top of the stack 
// values of S stacks by popping 
// at most N elements 
  
#include  
using namespace std; 
  
// Function for computing the 
// maximum sum at the top of 
// the stacks after popping at 
// most N elements from S stack 
int maximumSum(int S, int M, int N, 
            vector >& stacks) 
{ 
    // Constructing a dp matrix 
    // of dimensions (S+1) x (N+1) 
    int dp[S + 1][N + 1]; 
  
    // Initialize all states 
    memset(dp, INT_MIN, sizeof(dp)); 
  
    // Loop over all i stacks 
    for (int i = 0; i < S; i++) { 
        for (int j = 0; j <= N; j++) { 
            for (int k = 0; k <= min(j, M); k++) { 
  
                // Store the maximum of 
                // popping j elements 
                // up to the current stack 
                // by popping k elements 
                // from current stack and 
                // j - k elements from all 
                // previous stacks combined 
                dp[i + 1][j] 
                    = max(dp[i + 1][j], 
                        stacks[i][k] 
                            + dp[i][j - k]); 
            } 
        } 
    } 
  
    // Store the maximum sum of 
    // popping N elements across 
    // all stacks 
    int result = INT_MIN; 
    for (int i = 0; i <= N; i++) { 
        result = max(result, dp[S][i]); 
    } 
  
    // dp[S][N] has the maximum sum 
    return result; 
} 
  
// Driver Program 
int main() 
{ 
    // Number of stacks 
    int S = 2; 
    // Length of each stack 
    int M = 4; 
  
    vector > stacks = { 
        { 2, 6, 4, 5 }, 
        { 1, 6, 15, 10 } 
    }; 
  
    // Maximum elements that 
    // can be popped 
    int N = 3; 
  
    cout << maximumSum(S, M, N, stacks); 
  
    return 0; 
}


Java
// Java Program to maximize the
// sum of top of the stack
// values of S stacks by popping
// at most N elements
import java.util.*;
class GFG{
  
// Function for computing the
// maximum sum at the top of
// the stacks after popping at
// most N elements from S stack
static int maximumSum(int S, int M, int N,
                      int [][]stacks)
{
    // Constructing a dp matrix
    // of dimensions (S+1) x (N+1)
    int [][]dp = new int[S + 1][N + 1];
  
    // Loop over all i stacks
    for (int i = 0; i < S; i++)
    {
        for (int j = 0; j <= N; j++)
        {
            for (int k = 0; k <= Math.min(j, M); k++)
            {
  
                // Store the maximum of
                // popping j elements
                // up to the current stack
                // by popping k elements
                // from current stack and
                // j - k elements from all
                // previous stacks combined
                dp[i + 1][j] = Math.max(dp[i + 1][j], 
                                        stacks[i][k] + 
                                        dp[i][j - k]);
            }
        }
    }
  
    // Store the maximum sum of
    // popping N elements across
    // all stacks
    int result = Integer.MIN_VALUE;
    for (int i = 0; i <= N; i++) 
    {
        result = Math.max(result, dp[S][i]);
    }
  
    // dp[S][N] has the maximum sum
    return result;
}
  
// Driver Program
public static void main(String[] args)
{
    // Number of stacks
    int S = 2;
      
    // Length of each stack
    int M = 4;
  
    int [][]stacks = {{ 2, 6, 4, 5 },
                      { 1, 6, 15, 10 }};
  
    // Maximum elements that
    // can be popped
    int N = 3;
  
    System.out.print(maximumSum(S, M, N, stacks));
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 program to maximize the
# sum of top of the stack values 
# of S stacks by popping at most 
# N element
import sys
  
# Function for computing the
# maximum sum at the top of
# the stacks after popping at
# most N elements from S stack
def maximumSum(S, M, N, stacks):
  
    # Constructing a dp matrix
    # of dimensions (S+1) x (N+1)
    dp = [[0 for x in range(N + 1)] 
             for y in range(S + 1)]
  
    # Loop over all i stacks
    for i in range(S):
        for j in range(N + 1):
            for k in range(min(j, M) + 1):
                  
                # Store the maximum of
                # popping j elements
                # up to the current stack
                # by popping k elements
                # from current stack and
                # j - k elements from all
                # previous stacks combined
                dp[i + 1][j] = max(dp[i + 1][j], 
                                   stacks[i][k] + 
                                   dp[i][j - k])
  
    # Store the maximum sum of
    # popping N elements across
    # all stacks
    result = -sys.maxsize - 1
    for i in range(N + 1):
        result = max(result, dp[S][i])
  
    # dp[S][N] has the maximum sum
    return result
  
# Driver code
if __name__ == "__main__":
  
    # Number of stacks
    S = 2
      
    # Length of each stack
    M = 4
   
    stacks = [ [ 2, 6, 4, 5 ],
               [ 1, 6, 15, 10 ] ]
  
    # Maximum elements that
    # can be popped
    N = 3
  
    print(maximumSum(S, M, N, stacks))
  
# This code is contributed by chitranayal


C#
// C# program to maximize the sum 
// of top of the stack values of
// S stacks by popping at most N
// elements
using System;
  
class GFG{
  
// Function for computing the
// maximum sum at the top of
// the stacks after popping at
// most N elements from S stack
static int maximumSum(int S, int M, int N,
                      int [,]stacks)
{
      
    // Constructing a dp matrix
    // of dimensions (S+1) x (N+1)
    int [,]dp = new int[S + 1, N + 1];
  
    // Loop over all i stacks
    for(int i = 0; i < S; i++)
    {
        for(int j = 0; j <= N; j++)
        {
            for(int k = 0; 
                    k <= Math.Min(j, M); k++)
            {
                  
                // Store the maximum of popping
                // j elements up to the current
                // stack by popping k elements
                // from current stack and
                // j - k elements from all
                // previous stacks combined
                dp[i + 1, j] = Math.Max(dp[i + 1, j], 
                                        stacks[i, k] + 
                                        dp[i, j - k]);
            }
        }
    }
  
    // Store the maximum sum of
    // popping N elements across
    // all stacks
    int result = int.MinValue;
    for(int i = 0; i <= N; i++) 
    {
        result = Math.Max(result, dp[S, i]);
    }
  
    // dp[S,N] has the maximum sum
    return result;
}
  
// Driver code
public static void Main(String[] args)
{
      
    // Number of stacks
    int S = 2;
      
    // Length of each stack
    int M = 4;
  
    int [,]stacks = { { 2, 6, 4, 5 },
                      { 1, 6, 15, 10 } };
  
    // Maximum elements that
    // can be popped
    int N = 3;
  
    Console.Write(maximumSum(S, M, N, stacks));
}
}
  
// This code is contributed by 29AjayKumar


输出:
21

时间复杂度: O(S *(M + N *(min(N,M))