📌  相关文章
📜  每次删除数组一半后,以更大的总和最大化剩余元素的总和

📅  最后修改于: 2021-05-17 19:28:21             🧑  作者: Mango

给定一个由N个整数组成的数组arr [] ,任务是在每次删除具有最大和的数组一半后,添加剩余元素后,使得到的总和最大化。

例子:

天真的方法:解决问题的最简单方法是使用递归。步骤如下:

  1. 使用前缀总和的概念并初始化变量,例如res,以存储最终结果
  2. 创建字典。
  3. 遍历数组并将所有前缀和存储在字典中。
  4. 现在,在[0,N]范围内进行迭代,并将数组左半部分和右半部分的前缀和分别存储为
  5. 现在,存在三种可能的条件:
    • 左>右
    • 左<右
    • 左==右
  6. 对于上述所有条件,请忽略最大和,并将和中的最小值与结果和相加,然后继续进行递归调用。
  7. 在所有递归调用结束之后,输出结果总和的最大值

下面是上述方法的实现:

C++14
// C++14 program to implement
// the above approach
#include 
using namespace std;
 
// Function to find the maximum sum
int maxweight(int s, int e,
  unordered_map& pre)
{
     
    // Base case
    // len of array is 1
    if (s == e)
        return 0;
 
    // Stores the final result
    int ans = 0;
 
    // Traverse the array
    for(int i = s; i < e; i++)
    {
         
        // Store left prefix sum
        int left = pre[i] - pre[s - 1];
 
        // Store right prefix sum
        int right = pre[e] - pre[i];
 
        // Compare the left and right
        if (left < right)
            ans = max(ans, left +
                      maxweight(s, i, pre));
 
        // If both are equal apply
        // the optimal method
        if (left == right)
        {
            // Update with minimum
            ans = max({ans, left +
                       maxweight(s, i, pre),
                             right +
                       maxweight(i + 1, e, pre)});
        }
 
        if (left > right)
            ans = max(ans, right +
                     maxweight(i + 1, e, pre));
    }    
 
    // Return the final ans
    return ans;
}
 
// Function to print maximum sum
void maxSum(vector arr)
{
     
    // Dicitionary to store prefix sums
    unordered_map pre;
    pre[-1] = 0;
    pre[0] = arr[0];
 
    // Traversing the array
    for(int i = 1; i < arr.size(); i++)
    {
         
        // Add prefix sum of the array
        pre[i] = pre[i - 1] + arr[i];
    }
    cout << maxweight(0, arr.size() - 1, pre);
}
 
// Driver Code
int main()
{
    vector arr = { 6, 2, 3, 4, 5, 5 };
     
    // Function call
    maxSum(arr);
     
    return 0;
}
 
// This code is contributed by mohit kumar 29


Java
// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
     
// Function to find the maximum sum
static int maxweight(int s, int e,
                     Map pre)
{
     
    // Base case
    // len of array is 1
    if (s == e)
        return 0;
 
    // Stores the final result
    int ans = 0;
 
    // Traverse the array
    for(int i = s; i < e; i++)
    {
         
        // Store left prefix sum
        int left = pre.get(i) - pre.get(s - 1);
 
        // Store right prefix sum
        int right = pre.get(e) - pre.get(i);
 
        // Compare the left and right
        if (left < right)
            ans = Math.max(ans, left +
                           maxweight(s, i, pre));
 
        // If both are equal apply
        // the optimal method
        if (left == right)
        {
             
            // Update with minimum
            ans = Math.max(ans, Math.max(left +
                           maxweight(s, i, pre),
                           right + maxweight(i + 1,
                                             e, pre)));
        }
 
        if (left > right)
            ans = Math.max(ans, right +
                           maxweight(i + 1, e, pre));
    }    
     
    // Return the final ans
    return ans;
}
 
// Function to print maximum sum
static void maxSum(List arr)
{
     
    // To store prefix sums
    Map pre = new HashMap<>();
    pre.put(-1, 0);
    pre.put(0, arr.get(0));
 
    // Traversing the array
    for(int i = 1; i < arr.size(); i++)
    {
         
        // Add prefix sum of the array
        pre.put(i, pre.getOrDefault(i - 1, 0) +
                   arr.get(i));
    }
    System.out.println(maxweight(0,
                arr.size() - 1, pre));
}
 
// Driver code
public static void main (String[] args)
{
    List arr = Arrays.asList(6, 2, 3,
                                      4, 5, 5);
     
    // Function call
    maxSum(arr);
}
}
 
// This code is contributed by offbeat


Python3
# Python3 program to implement
# the above approach
 
# Function to find the maximum sum
def maxweight(s, e, pre):
 
    # Base case
    # len of array is 1
    if s == e:
        return 0
 
    # Stores the final result
    ans = 0
 
    # Traverse the array
    for i in range(s, e):
 
        # Store left prefix sum
        left = pre[i] - pre[s - 1]
 
        # Store right prefix sum
        right = pre[e] - pre[i]
 
        # Compare the left and right
        if left < right:
            ans = max(ans, left \
            + maxweight(s, i, pre))
 
        # If both are equal apply
        # the optimal method
        if left == right:
 
            # Update with minimum
            ans = max(ans, left \
                  + maxweight(s, i, pre),
                    right \
                  + maxweight(i + 1, e, pre))
 
        if left > right:
            ans = max(ans, right \
                  + maxweight(i + 1, e, pre))
 
    # Return the final ans
    return ans
 
# Function to print maximum sum
def maxSum(arr):
 
    # Dicitionary to store prefix sums
    pre = {-1: 0, 0: arr[0]}
 
    # Traversing the array
    for i in range(1, len(arr)):
 
        # Add prefix sum of the array
        pre[i] = pre[i - 1] + arr[i]
     
    print(maxweight(0, len(arr) - 1, pre))
 
# Drivers Code
 
arr = [6, 2, 3, 4, 5, 5]
 
# Function Call
maxSum(arr)


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
     
// Function to find the maximum sum
static int maxweight(int s, int e,
                     Dictionary pre)
{
  // Base case
  // len of array is 1
  if (s == e)
    return 0;
 
  // Stores the
  // readonly result
  int ans = 0;
 
  // Traverse the array
  for(int i = s; i < e; i++)
  {
    // Store left prefix sum
    int left = pre[i] - pre[s - 1];
 
    // Store right prefix sum
    int right = pre[e] - pre[i];
 
    // Compare the left and right
    if (left < right)
      ans = Math.Max(ans, left +
            maxweight(s, i, pre));
 
    // If both are equal apply
    // the optimal method
    if (left == right)
    {
      // Update with minimum
      ans = Math.Max(ans, Math.Max(left +
                          maxweight(s, i, pre),
                          right + maxweight(i + 1,
                                            e, pre)));
    }
 
    if (left > right)
      ans = Math.Max(ans, right +
            maxweight(i + 1, e, pre));
  }    
 
  // Return the readonly ans
  return ans;
}
 
// Function to print maximum sum
static void maxSum(List arr)
{
     
  // To store prefix sums
  Dictionary pre = new Dictionary();
  pre.Add(-1, 0);
  pre.Add(0, arr[0]);
 
  // Traversing the array
  for(int i = 1; i < arr.Count; i++)
  {
    // Add prefix sum of the array
    if(pre[i - 1] != 0)
      pre.Add(i, pre[i - 1] + arr[i]);
    else
      pre.Add(i, arr[i]);
  }
  Console.WriteLine(maxweight(0,
                    arr.Count - 1, pre));
}
 
// Driver code
public static void Main(String[] args)
{
  List arr = new List();
  arr.Add(6);
  arr.Add(2);
  arr.Add(3);
  arr.Add(4);
  arr.Add(5);
  arr.Add(5);
 
  // Function call
  maxSum(arr);
}
}
 
// This code is contributed by gauravrajput1


C++
// C++ program to implement
// the above approach
#include 
using namespace std;
 
int dp[100][100];
 
// Function to find the maximum sum
int maxweight(int s, int e,
          map pre)
{
     
    // Base Case
    if (s == e)
        return 0;
 
    // Create a key to map
    // the values
 
    // Check if (mapped key is
    // found in the dictionary
    if (dp[s][e] != -1)
        return dp[s][e];
 
    int ans = 0;
 
    // Traverse the array
    for(int i = s; i < e; i++)
    {
         
        // Store left prefix sum
        int left = pre[i] - pre[s - 1];
 
        // Store right prefix sum
        int right = pre[e] - pre[i];
 
        // Compare the left and
        // right values
        if (left < right)
            ans = max(
                ans, (int)(left +
                           maxweight(s, i, pre)));
 
        if (left == right)
            ans = max(
                ans, max(left + maxweight(s, i,
                                          pre),
                         right + maxweight(i + 1,
                                           e, pre)));
 
        if (left > right)
            ans = max(
                ans, right + maxweight(i + 1, e, pre));
 
        // Store the value in dp array
        dp[s][e] = ans;
    }
 
    // Return the final answer
    return dp[s][e];
}
 
// Function to print maximum sum
void maxSum(int arr[], int n)
{
     
    // Stores prefix sum
    map pre;
    pre[-1] = 0;
    pre[0] = arr[0];
 
    // Store results of subproblems
    memset(dp, -1, sizeof dp);
 
    // Traversing the array
    for(int i = 0; i < n; i++)
 
        // Add prefix sum of array
        pre[i] = pre[i - 1] + arr[i];
 
    // Print the answer
    cout << (maxweight(0, n - 1, pre));
}
 
// Driver Code
int main()
{
    int arr[] = { 6, 2, 3, 4, 5, 5 };
 
    // Function call
    maxSum(arr, 6);
}
 
// This code is contributed by grand_master


Java
// Java program to implement
// the above approach
import java.util.*;
 
class solution{
    
static int[][] dp = new int[100][100];
 
// Function to find the maximum sum
static int maxweight(int s, int e,
                     HashMap pre)
{
     
    // Base Case
    if (s == e)
        return 0;
 
    // Create a key to map
    // the values
 
    // Check if (mapped key is
    // found in the dictionary
    if (dp[s][e] != -1)
        return dp[s][e];
 
    int ans = 0;
 
    // Traverse the array
    for(int i = s; i < e; i++)
    {
         
        // Store left prefix sum
        int left = pre.get(i) -
                   pre.get(s - 1);
 
        // Store right prefix sum
        int right = pre.get(e) -
                    pre.get(i);
 
        // Compare the left and
        // right values
        if (left < right)
            ans = Math.max(ans, (int)(left +
                           maxweight(s, i, pre)));
 
        if (left == right)
            ans = Math.max(ans,
                           Math.max(left + maxweight(s, i,
                                                     pre),
                                    right + maxweight(i + 1,
                                                      e, pre)));
 
        if (left > right)
            ans = Math.max(ans, right + maxweight(i + 1,
                                                  e, pre));
 
        // Store the value in dp array
        dp[s][e] = ans;
    }
     
    // Return the final answer
    return dp[s][e];
}
 
// Function to print maximum sum
static void maxSum(int arr[], int n)
{
     
    // Stores prefix sum
    HashMap pre = new HashMap();
    pre.put(-1, 0);
    pre.put(0, arr[0]);
 
    // Store results of subproblems
    for(int i = 0; i < 100; i++)
    {
        for(int j = 0; j < 100; j++)
          dp[i][j] = -1;
    }
 
    // Traversing the array
    for(int i = 0; i < n; i++)
 
        // Add prefix sum of array
        pre.put(i, pre.get(i - 1) + arr[i]);
 
    // Print the answer
    System.out.print((maxweight(0, n - 1, pre)));
}
 
// Driver Code
public static void main(String args[])
{
    int []arr = { 6, 2, 3, 4, 5, 5 };
     
    // Function call
    maxSum(arr, 6);
}
}
 
// This code is contributed by Surendra_Gangwar


Python3
# Python3 program to implement
# the above approach
 
# Function to find the maximum sum
def maxweight(s, e, pre, dp):
 
    # Base Case 
    if s == e:
        return 0
 
    # Create a key to map
    # the values
    key = (s, e)
    
    # Check if mapped key is
    # found in the dictionary
    if key in dp:
        return dp[key]
 
    ans = 0
 
    # Traverse the array
    for i in range(s, e):
 
         # Store left prefix sum
        left = pre[i] - pre[s-1]
  
        # Store right prefix sum
        right = pre[e] - pre[i]
 
        # Compare the left and
        # right values
        if left < right:
            ans = max(ans, left \
                + maxweight(s, i, pre, dp))
 
        if left == right:
 
            # Update with minimum
            ans = max(ans, left \
                  + maxweight(s, i, pre, dp),
                  right \
                  + maxweight(i + 1, e, pre, dp))
 
        if left > right:
           ans = max(ans, right \
                 + maxweight(i + 1, e, pre, dp))
 
        # Store the value in dp array
        dp[key] = ans
 
    # Return the final answer
    return dp[key]
 
# Function to print maximum sum
def maxSum(arr):
 
    # Stores prefix sum
    pre = {-1: 0, 0: arr[0]}
 
    # Store results of subproblems
    dp = {}
 
    # Traversing the array
    for i in range(1, len(arr)):
         
        # Add prefix sum of array
        pre[i] = pre[i - 1] + arr[i]
 
    # Print the answer
    print(maxweight(0, len(arr) - 1, pre, dp))
 
# Driver Code
 
arr = [6, 2, 3, 4, 5, 5]
 
# Function Call
maxSum(arr)


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
 
class GFG{
    
static int[,] dp = new int[100, 100];
 
// Function to find the maximum sum
static int maxweight(int s, int e,
          Dictionary pre)
{
     
    // Base Case
    if (s == e)
        return 0;
 
    // Create a key to map
    // the values
 
    // Check if (mapped key is
    // found in the dictionary
    if (dp[s, e] != -1)
        return dp[s, e];
 
    int ans = 0;
 
    // Traverse the array
    for(int i = s; i < e; i++)
    {
         
        // Store left prefix sum
        int left = pre[i] -
                   pre[s - 1];
 
        // Store right prefix sum
        int right = pre[e] -
                    pre[i];
 
        // Compare the left and
        // right values
        if (left < right)
            ans = Math.Max(ans, (int)(left +
                           maxweight(s, i, pre)));
 
        if (left == right)
            ans = Math.Max(ans,
                           Math.Max(left + maxweight(s, i,
                                                     pre),
                                   right + maxweight(i + 1,
                                                     e, pre)));
 
        if (left > right)
            ans = Math.Max(ans, right + maxweight(i + 1,
                                                  e, pre));
 
        // Store the value in dp array
        dp[s, e] = ans;
    }
     
    // Return the readonly answer
    return dp[s, e];
}
 
// Function to print maximum sum
static void maxSum(int []arr, int n)
{
     
    // Stores prefix sum
    Dictionary pre = new Dictionary();
    pre.Add(-1, 0);
    pre.Add(0, arr[0]);
 
    // Store results of subproblems
    for(int i = 0; i < 100; i++)
    {
        for(int j = 0; j < 100; j++)
          dp[i, j] = -1;
    }
 
    // Traversing the array
    for(int i = 1; i < n; i++)
 
        // Add prefix sum of array
        pre.Add(i, pre[i - 1] + arr[i]);
 
    // Print the answer
    Console.Write((maxweight(0, n - 1, pre)));
}
 
// Driver Code
public static void Main(String []args)
{
    int []arr = { 6, 2, 3, 4, 5, 5 };
     
    // Function call
    maxSum(arr, 6);
}
}
 
// This code is contributed by Amit Katiyar


输出:
18















时间复杂度: O(2 N )
辅助空间: O(N 2 )

高效的方法:为了优化上述方法,我们的想法是观察到存在许多重复的子问题。
因此,为了进行优化,请使用动态编程。想法是使用字典并跟踪结果值,以便在进一步的计算中需要它们时可以直接访问它们而无需再次计算它们。

下面是上述方法的实现:

C++

// C++ program to implement
// the above approach
#include 
using namespace std;
 
int dp[100][100];
 
// Function to find the maximum sum
int maxweight(int s, int e,
          map pre)
{
     
    // Base Case
    if (s == e)
        return 0;
 
    // Create a key to map
    // the values
 
    // Check if (mapped key is
    // found in the dictionary
    if (dp[s][e] != -1)
        return dp[s][e];
 
    int ans = 0;
 
    // Traverse the array
    for(int i = s; i < e; i++)
    {
         
        // Store left prefix sum
        int left = pre[i] - pre[s - 1];
 
        // Store right prefix sum
        int right = pre[e] - pre[i];
 
        // Compare the left and
        // right values
        if (left < right)
            ans = max(
                ans, (int)(left +
                           maxweight(s, i, pre)));
 
        if (left == right)
            ans = max(
                ans, max(left + maxweight(s, i,
                                          pre),
                         right + maxweight(i + 1,
                                           e, pre)));
 
        if (left > right)
            ans = max(
                ans, right + maxweight(i + 1, e, pre));
 
        // Store the value in dp array
        dp[s][e] = ans;
    }
 
    // Return the final answer
    return dp[s][e];
}
 
// Function to print maximum sum
void maxSum(int arr[], int n)
{
     
    // Stores prefix sum
    map pre;
    pre[-1] = 0;
    pre[0] = arr[0];
 
    // Store results of subproblems
    memset(dp, -1, sizeof dp);
 
    // Traversing the array
    for(int i = 0; i < n; i++)
 
        // Add prefix sum of array
        pre[i] = pre[i - 1] + arr[i];
 
    // Print the answer
    cout << (maxweight(0, n - 1, pre));
}
 
// Driver Code
int main()
{
    int arr[] = { 6, 2, 3, 4, 5, 5 };
 
    // Function call
    maxSum(arr, 6);
}
 
// This code is contributed by grand_master

Java

// Java program to implement
// the above approach
import java.util.*;
 
class solution{
    
static int[][] dp = new int[100][100];
 
// Function to find the maximum sum
static int maxweight(int s, int e,
                     HashMap pre)
{
     
    // Base Case
    if (s == e)
        return 0;
 
    // Create a key to map
    // the values
 
    // Check if (mapped key is
    // found in the dictionary
    if (dp[s][e] != -1)
        return dp[s][e];
 
    int ans = 0;
 
    // Traverse the array
    for(int i = s; i < e; i++)
    {
         
        // Store left prefix sum
        int left = pre.get(i) -
                   pre.get(s - 1);
 
        // Store right prefix sum
        int right = pre.get(e) -
                    pre.get(i);
 
        // Compare the left and
        // right values
        if (left < right)
            ans = Math.max(ans, (int)(left +
                           maxweight(s, i, pre)));
 
        if (left == right)
            ans = Math.max(ans,
                           Math.max(left + maxweight(s, i,
                                                     pre),
                                    right + maxweight(i + 1,
                                                      e, pre)));
 
        if (left > right)
            ans = Math.max(ans, right + maxweight(i + 1,
                                                  e, pre));
 
        // Store the value in dp array
        dp[s][e] = ans;
    }
     
    // Return the final answer
    return dp[s][e];
}
 
// Function to print maximum sum
static void maxSum(int arr[], int n)
{
     
    // Stores prefix sum
    HashMap pre = new HashMap();
    pre.put(-1, 0);
    pre.put(0, arr[0]);
 
    // Store results of subproblems
    for(int i = 0; i < 100; i++)
    {
        for(int j = 0; j < 100; j++)
          dp[i][j] = -1;
    }
 
    // Traversing the array
    for(int i = 0; i < n; i++)
 
        // Add prefix sum of array
        pre.put(i, pre.get(i - 1) + arr[i]);
 
    // Print the answer
    System.out.print((maxweight(0, n - 1, pre)));
}
 
// Driver Code
public static void main(String args[])
{
    int []arr = { 6, 2, 3, 4, 5, 5 };
     
    // Function call
    maxSum(arr, 6);
}
}
 
// This code is contributed by Surendra_Gangwar

Python3

# Python3 program to implement
# the above approach
 
# Function to find the maximum sum
def maxweight(s, e, pre, dp):
 
    # Base Case 
    if s == e:
        return 0
 
    # Create a key to map
    # the values
    key = (s, e)
    
    # Check if mapped key is
    # found in the dictionary
    if key in dp:
        return dp[key]
 
    ans = 0
 
    # Traverse the array
    for i in range(s, e):
 
         # Store left prefix sum
        left = pre[i] - pre[s-1]
  
        # Store right prefix sum
        right = pre[e] - pre[i]
 
        # Compare the left and
        # right values
        if left < right:
            ans = max(ans, left \
                + maxweight(s, i, pre, dp))
 
        if left == right:
 
            # Update with minimum
            ans = max(ans, left \
                  + maxweight(s, i, pre, dp),
                  right \
                  + maxweight(i + 1, e, pre, dp))
 
        if left > right:
           ans = max(ans, right \
                 + maxweight(i + 1, e, pre, dp))
 
        # Store the value in dp array
        dp[key] = ans
 
    # Return the final answer
    return dp[key]
 
# Function to print maximum sum
def maxSum(arr):
 
    # Stores prefix sum
    pre = {-1: 0, 0: arr[0]}
 
    # Store results of subproblems
    dp = {}
 
    # Traversing the array
    for i in range(1, len(arr)):
         
        # Add prefix sum of array
        pre[i] = pre[i - 1] + arr[i]
 
    # Print the answer
    print(maxweight(0, len(arr) - 1, pre, dp))
 
# Driver Code
 
arr = [6, 2, 3, 4, 5, 5]
 
# Function Call
maxSum(arr)

C#

// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
 
class GFG{
    
static int[,] dp = new int[100, 100];
 
// Function to find the maximum sum
static int maxweight(int s, int e,
          Dictionary pre)
{
     
    // Base Case
    if (s == e)
        return 0;
 
    // Create a key to map
    // the values
 
    // Check if (mapped key is
    // found in the dictionary
    if (dp[s, e] != -1)
        return dp[s, e];
 
    int ans = 0;
 
    // Traverse the array
    for(int i = s; i < e; i++)
    {
         
        // Store left prefix sum
        int left = pre[i] -
                   pre[s - 1];
 
        // Store right prefix sum
        int right = pre[e] -
                    pre[i];
 
        // Compare the left and
        // right values
        if (left < right)
            ans = Math.Max(ans, (int)(left +
                           maxweight(s, i, pre)));
 
        if (left == right)
            ans = Math.Max(ans,
                           Math.Max(left + maxweight(s, i,
                                                     pre),
                                   right + maxweight(i + 1,
                                                     e, pre)));
 
        if (left > right)
            ans = Math.Max(ans, right + maxweight(i + 1,
                                                  e, pre));
 
        // Store the value in dp array
        dp[s, e] = ans;
    }
     
    // Return the readonly answer
    return dp[s, e];
}
 
// Function to print maximum sum
static void maxSum(int []arr, int n)
{
     
    // Stores prefix sum
    Dictionary pre = new Dictionary();
    pre.Add(-1, 0);
    pre.Add(0, arr[0]);
 
    // Store results of subproblems
    for(int i = 0; i < 100; i++)
    {
        for(int j = 0; j < 100; j++)
          dp[i, j] = -1;
    }
 
    // Traversing the array
    for(int i = 1; i < n; i++)
 
        // Add prefix sum of array
        pre.Add(i, pre[i - 1] + arr[i]);
 
    // Print the answer
    Console.Write((maxweight(0, n - 1, pre)));
}
 
// Driver Code
public static void Main(String []args)
{
    int []arr = { 6, 2, 3, 4, 5, 5 };
     
    // Function call
    maxSum(arr, 6);
}
}
 
// This code is contributed by Amit Katiyar
输出:
18















时间复杂度: O(N 3 )
辅助空间: O(N 2 )