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

📅  最后修改于: 2021-09-17 16:05:12             🧑  作者: Mango

给定长度为M 的S 个堆栈,任务是通过最多弹出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. 这 j 个元素可以从已经访问过的所有 i 个堆栈中选择。因此, dp[i+1][j]存储k的所有值的最大值stacks[i][k] + dp[i][j – k] ,范围从0 到 min(j, size of stack) 。关系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


Javascript


输出:
21

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