给定S个长度为M的堆栈,任务是通过弹出最多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)个元素来计算最大可能的和。
- 可以从已经访问过的所有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个元素而可能得到的最大和。
- 对所有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
21
时间复杂度: O(S *(M + N *(min(N,M))