给定长度为M 的S 个堆栈,任务是通过最多弹出N 个元素来最大化每个堆栈顶部的元素总和。
例子:
Input: S = 1, N = 3, stacks = { 5, 1, 2, 8, 9 }
Output: 8
Explanation:
Maximum 3 elements can be removed.
The current element at the top of the stack is 5.
On removal of 5, the new element at the top is 1.
On removal of 1, the new element at the top is 2.
On removal of 2, the new element at the top is 8.
No further pop operation is allowed.
Hence, the maximum possible value at the top of the stack is 8.
Input: S = 2, N = 2, stacks = { { 2, 6, 4, 5}, {1, 6, 15, 10} }
Output: 17
Explanation:
Current sum of the elements at the top = 2 + 1 = 3.
Popping 1 from top of the second stack only makes the sum 8 (5 + 2 = 8)
Popping 2 from the top of the second stack only makes the sum 7 (6 + 1).
Popping both 1 and 2 from the top of each stack makes the sum 12 (6 + 6).
Popping 2 and 6 from the first stack makes the sum 5 (4 + 1).
Popping 1 and 6 from the second stack leaves 15 as the element at the top.
Hence, the sum of elements at the top of the two stacks is maximized (15 + 2 = 17).
方法:这个问题可以简化为 0/1 背包问题。要解决此问题,请按照以下步骤操作:
- 创建一个具有(S + 1)行和(N + 1)列的二维表dp[][] 。在每个索引dp[i][j] 处,通过将j 个元素弹出到第i个堆栈来存储可能的最大总和。
- 将所有索引dp[][]初始化为 0。
- 迭代从 i = 0 到 S – 1 的每个堆栈
- 现在,对于每个第i个堆栈,通过弹出 j(1 到 N)个元素来计算最大可能总和。
- 这 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 个元素获得的最大和。
- 一次,对所有i堆栈完成后,找到范围[1, N – 1]内所有 i 的dp[S][i]最大值。
- 上一步得到的最大值就是要求的答案。
下面的代码是上述方法的实现:
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))
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live