📌  相关文章
📜  通过删除相等元素的连续子数组来最大化清空数组的成本

📅  最后修改于: 2021-09-04 08:08:22             🧑  作者: Mango

给定一个由N 个整数和一个整数M组成的数组arr[] ,任务是找到通过执行以下操作任意次数可以获得的最大成本。

例子:

方法:这个问题可以用动态规划解决。以下是步骤:

  1. 初始化 3D 数组dp[][][]使得dp[left][right][count] ,其中leftright表示索引[left, right]之间的操作, countarr[左侧的元素数left]arr[ left]具有相同的值,并且计数不包括arr[left]
  2. 现在有以下两种可能的选择:
    • 结束序列以移除具有相同值的元素,包括起始元素(即arr[left] ),然后从下一个元素开始继续。
    • 继续序列以在索引[left + 1, right]之间搜索与arr[left]具有相同值的元素(比如索引i ),这使我们能够继续序列。
  3. 从新序列进行递归调用并继续前一个序列的过程。
  4. 打印所有上述步骤后的最大成本。

下面是上述方法的实现:

C++
// C++ program for the above approach
  
#include 
using namespace std;
  
// Initialize dp array
int dp[101][101][101];
  
// Function that removes elements
// from array to maximize the cost
int helper(int arr[], int left, int right,
           int count, int m)
{
    // Base case
    if (left > right)
        return 0;
  
    // Check if an answer is stored
    if (dp[left][right][count] != -1) {
        return dp[left][right][count];
    }
  
    // Deleting count + 1 i.e. including
    // the first element and starting a
    // new sequence
    int ans = (count + 1) * m
              + helper(arr, left + 1,
                       right, 0, m);
  
    for (int i = left + 1;
         i <= right; ++i) {
  
        if (arr[i] == arr[left]) {
  
            // Removing [left + 1, i - 1]
            // elements to continue with
            // previous sequence
            ans = max(
                ans,
                helper(arr, left + 1,
                       i - 1, 0, m)
                    + helper(arr, i, right,
                             count + 1, m));
        }
    }
  
    // Store the result
    dp[left][right][count] = ans;
  
    // Return answer
    return ans;
}
  
// Function to remove the elements
int maxPoints(int arr[], int n, int m)
{
    int len = n;
    memset(dp, -1, sizeof(dp));
  
    // Function Call
    return helper(arr, 0, len - 1, 0, m);
}
  
// Driver Code
int main()
{
    // Given array
    int arr[] = { 1, 3, 2, 2, 2, 3, 4, 3, 1 };
  
    int M = 3;
  
    int N = sizeof(arr) / sizeof(arr[0]);
  
    // Function Call
    cout << maxPoints(arr, N, M);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
  
class GFG{
  
// Initialize dp array
static int [][][]dp = new int[101][101][101];
  
// Function that removes elements
// from array to maximize the cost
static int helper(int arr[], int left, int right,
                  int count, int m)
{
      
    // Base case
    if (left > right)
        return 0;
  
    // Check if an answer is stored
    if (dp[left][right][count] != -1) 
    {
        return dp[left][right][count];
    }
  
    // Deleting count + 1 i.e. including
    // the first element and starting a
    // new sequence
    int ans = (count + 1) * m + 
             helper(arr, left + 1,
                    right, 0, m);
  
    for(int i = left + 1; i <= right; ++i)
    {
        if (arr[i] == arr[left]) 
        {
              
            // Removing [left + 1, i - 1]
            // elements to continue with
            // previous sequence
            ans = Math.max(ans,
                  helper(arr, left + 1,
                         i - 1, 0, m) + 
                  helper(arr, i, right,
                         count + 1, m));
        }
    }
  
    // Store the result
    dp[left][right][count] = ans;
  
    // Return answer
    return ans;
}
  
// Function to remove the elements
static int maxPoints(int arr[], int n, int m)
{
    int len = n;
    for(int i = 0; i < 101; i++) 
    {
        for(int j = 0; j < 101; j++)
        {
            for(int k = 0; k < 101; k++)
                dp[i][j][k] = -1;
        }
    }
  
    // Function call
    return helper(arr, 0, len - 1, 0, m);
}
  
// Driver Code
public static void main(String[] args)
{
      
    // Given array
    int arr[] = { 1, 3, 2, 2, 2, 3, 4, 3, 1 };
  
    int M = 3;
  
    int N = arr.length;
  
    // Function call
    System.out.print(maxPoints(arr, N, M));
}
}
  
// This code is contributed by Amit Katiyar


Python3
# Python3 program for 
# the above approach
  
# Initialize dp array
dp = [[[-1 for x in range(101)]
            for y in range(101)]
            for z in range(101)]
   
# Function that removes elements
# from array to maximize the cost
def helper(arr, left, 
           right, count, m):
  
  # Base case
  if (left > right):
    return 0
  
  # Check if an answer is stored
  if (dp[left][right][count] != -1):
    return dp[left][right][count]
  
  # Deleting count + 1 i.e. including
  # the first element and starting a
  # new sequence
  ans = ((count + 1) * m + 
          helper(arr, left + 1,
                 right, 0, m))
  
  for i in range (left + 1,
                  right + 1):
  
    if (arr[i] == arr[left]):
  
      # Removing [left + 1, i - 1]
      # elements to continue with
      # previous sequence
      ans = (max(ans, helper(arr, left + 1,
                             i - 1, 0, m) + 
                         helper(arr, i, right,
                              count + 1, m)))
  
      # Store the result
      dp[left][right][count] = ans
  
      # Return answer
      return ans
   
# Function to remove the elements
def maxPoints(arr, n, m):
  length = n
  global dp
  
  # Function Call
  return helper(arr, 0, 
                length - 1, 0, m)
   
# Driver Code
if __name__ == "__main__":
  
  # Given array
  arr = [1, 3, 2, 2, 
         2, 3, 4, 3, 1]
  M = 3
  N = len(arr)
  
  # Function Call
  print(maxPoints(arr, N, M))
      
# This code is contributed by Chitranayal


C#
// C# program for the above approach
using System;
  
class GFG{
  
// Initialize dp array
static int [,,]dp = new int[101, 101, 101];
  
// Function that removes elements
// from array to maximize the cost
static int helper(int []arr, int left, int right,
                  int count, int m)
{
      
    // Base case
    if (left > right)
        return 0;
  
    // Check if an answer is stored
    if (dp[left, right, count] != -1) 
    {
        return dp[left, right, count];
    }
  
    // Deleting count + 1 i.e. including
    // the first element and starting a
    // new sequence
    int ans = (count + 1) * m + 
              helper(arr, left + 1,
                    right, 0, m);
  
    for(int i = left + 1; i <= right; ++i)
    {
        if (arr[i] == arr[left]) 
        {
              
            // Removing [left + 1, i - 1]
            // elements to continue with
            // previous sequence
            ans = Math.Max(ans,
                  helper(arr, left + 1,
                         i - 1, 0, m) + 
                  helper(arr, i, right,
                         count + 1, m));
        }
    }
  
    // Store the result
    dp[left, right, count] = ans;
  
    // Return answer
    return ans;
}
  
// Function to remove the elements
static int maxPoints(int []arr, int n, int m)
{
    int len = n;
    for(int i = 0; i < 101; i++) 
    {
        for(int j = 0; j < 101; j++)
        {
            for(int k = 0; k < 101; k++)
                dp[i, j, k] = -1;
        }
    }
  
    // Function call
    return helper(arr, 0, len - 1, 0, m);
}
  
// Driver Code
public static void Main(String[] args)
{
      
    // Given array
    int []arr = { 1, 3, 2, 2, 2, 3, 4, 3, 1 };
  
    int M = 3;
  
    int N = arr.Length;
  
    // Function call
    Console.Write(maxPoints(arr, N, M));
}
}
  
// This code is contributed by Amit Katiyar


输出:
27

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live