给定的大小N和整数K,阵列的,则任务是将阵列分成K个片段使得最小K个片段中的总和被最大化分裂。
例子:
Input: a[] = {5, 7, 4, 2, 8, 1, 6}, K = 3
Output: 7
Divide the array at indexes 0 and 1. Then the segments are {5}, {7}, {4, 2, 8, 1, 6}. Sum of the minimus is 5 + 7 + 1 = 13
Input: a[] = {6, 5, 3, 8, 9, 10, 4, 7, 10}, K = 4
Output: 27
方法:这个问题可以使用动态规划来解决。使用递归尝试所有可能的分区。令dp[i][k]是直到索引 i 与 k 个分区的最小值的最大总和。因此,可能的状态将在从索引 i 到 n 的每个索引处进行分区。所有这些状态的最小值的最大总和将是我们的答案。写完这个递归后,我们就可以使用memorize了。
下面是上述方法的实现:
C++
// C++ program to find the sum of
// the minimum of all the segments
#include
using namespace std;
const int MAX = 10;
// Function to maximize the sum of the minimums
int maximizeSum(int a[], int n, int ind,
int k, int dp[MAX][MAX])
{
// If k segments have been divided
if (k == 0) {
// If we are at the end
if (ind == n)
return 0;
// If we donot reach the end
// then return a negative number
// that cannot be the sum
else
return -1e9;
}
// If at the end but
// k segments are not formed
else if (ind == n)
return -1e9;
// If the state has not been visited yet
else if (dp[ind][k] != -1)
return dp[ind][k];
// If the state has not been visited
else {
int ans = 0;
// Get the minimum element in the segment
int mini = a[ind];
// Iterate and try to break at every index
// and create a segment
for (int i = ind; i < n; i++) {
// Find the minimum element in the segment
mini = min(mini, a[i]);
// Find the sum of all the segments trying all
// the possible combinations
ans = max(ans, maximizeSum(
a, n, i + 1, k - 1, dp) + mini);
}
// Return the answer by
// memoizing it
return dp[ind][k] = ans;
}
}
// Driver Code
int main()
{
int a[] = { 5, 7, 4, 2, 8, 1, 6 };
int k = 3;
int n = sizeof(a) / sizeof(a[0]);
// Initialize dp array with -1
int dp[MAX][MAX];
memset(dp, -1, sizeof dp);
cout << maximizeSum(a, n, 0, k, dp);
return 0;
}
Java
// Java program to find the sum of
// the minimum of all the segments
class GFG
{
static int MAX = 10;
// Function to maximize the
// sum of the minimums
public static int maximizeSum(
int[] a, int n, int ind,
int k, int[][] dp)
{
// If k segments have been divided
if (k == 0)
{
// If we are at the end
if (ind == n)
return 0;
// If we donot reach the end
// then return a negative number
// that cannot be the sum
else
return -1000000000;
}
// If at the end but
// k segments are not formed
else if (ind == n)
return -1000000000;
// If the state has not
// been visited yet
else if (dp[ind][k] != -1)
return dp[ind][k];
// If the state has
// not been visited
else
{
int ans = 0;
// Get the minimum
// element in the segment
int mini = a[ind];
// Iterate and try to break
// at every index
// and create a segment
for (int i = ind; i < n; i++)
{
// Find the minimum element
// in the segment
mini = Math.min(mini, a[i]);
// Find the sum of all the
// segments trying all
// the possible combinations
ans = Math.max(ans,
maximizeSum(a, n, i + 1,
k - 1, dp) + mini);
}
// Return the answer by
// memoizing it
return dp[ind][k] = ans;
}
}
// Driver Code
public static void main(String[] args)
{
int[] a = { 5, 7, 4, 2, 8, 1, 6 };
int k = 3;
int n = a.length;
// Initialize dp array with -1
int[][] dp = new int[MAX][MAX];
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
dp[i][j] = -1;
}
System.out.println(
maximizeSum(a, n, 0, k, dp));
}
}
// This code is contributed by
// sanjeev2552
Python3
# Python 3 program to find the sum of
# the minimum of all the segments
MAX = 10
# Function to maximize the
# sum of the minimums
def maximizeSum(a,n, ind, k, dp):
# If k segments have been divided
if (k == 0):
# If we are at the end
if (ind == n):
return 0
# If we donot reach the end
# then return a negative number
# that cannot be the sum
else:
return -1e9
# If at the end but
# k segments are not formed
elif (ind == n):
return -1e9
# If the state has been visited already
elif (dp[ind][k] != -1):
return dp[ind][k]
# If the state has not been visited
else:
ans = 0
# Get the minimum element
# in the segment
mini = a[ind]
# Iterate and try to break
# at every index
# and create a segment
for i in range(ind,n,1):
# Find the minimum element
# in the segment
mini = min(mini, a[i])
# Find the sum of all the
# segments trying all
# the possible combinations
ans = max(ans, maximizeSum(\
a, n, i + 1, k - 1, dp) + mini)
# Return the answer by
# memoizing it
dp[ind][k] = ans
return ans
# Driver Code
if __name__ == '__main__':
a = [5, 7, 4, 2, 1, 6]
k = 3
n = len(a)
# Initialize dp array with -1
dp = [[-1 for i in range(MAX)]\
for j in range(MAX)]
print(maximizeSum(a, n, 0, k, dp))
# This code is contributed by
# Surendra_Gangwar
C#
// C# program to find the sum of
// the minimum of all the segments
using System;
class GFG
{
static int MAX = 10;
// Function to maximize the sum of the minimums
public static int maximizeSum(
int[] a, int n, int ind,
int k, int[] dp)
{
// If k segments have been divided
if (k == 0)
{
// If we are at the end
if (ind == n)
return 0;
// If we donot reach the end
// then return a negative number
// that cannot be the sum
else
return -1000000000;
}
// If at the end but
// k segments are not formed
else if (ind == n)
return -1000000000;
// If the state has not
// been visited yet
else if (dp[ind, k] != -1)
return dp[ind, k];
// If the state has not been visited
else
{
int ans = 0;
// Get the minimum element
// in the segment
int mini = a[ind];
// Iterate and try to break
// at every index
// and create a segment
for (int i = ind; i < n; i++)
{
// Find the minimum element
// in the segment
mini = Math.Min(mini, a[i]);
// Find the sum of all the
// segments trying all
// the possible combinations
ans = Math.Max(ans,
maximizeSum(a, n, i + 1,
k - 1, dp) + mini);
}
// Return the answer by
// memoizing it
return dp[ind,k] = ans;
}
}
// Driver Code
public static void Main(String[] args)
{
int[] a = { 5, 7, 4, 2, 8, 1, 6 };
int k = 3;
int n = a.Length;
// Initialize dp array with -1
int[,] dp = new int[MAX, MAX];
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
dp[i, j] = -1;
}
Console.WriteLine(
maximizeSum(a, n, 0, k, dp));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出
13
时间复杂度:O(N * N * K)
辅助空间:O(N * K)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。