给定由N个整数和整数M组成的数组arr [] ,任务是找到可以通过多次执行以下操作获得的最大成本。
In one operation, choose K contiguous elements with same value(where K ≥ 1) and remove them and cost of this operation is K * M.
例子:
Input: arr[] = {1, 3, 2, 2, 2, 3, 4, 3, 1}, M = 3
Output: 27
Explanation:
Step 1: Remove three contiguous 2’s to modify arr[] = {1, 3, 3, 4, 3, 1}. Cost = 3 * 3 = 9
Step 2: Remove 4 to modify arr[] = {1, 3, 3, 3, 1}. Cost = 9 + 1 * 3 = 12
Step 3: Remove three contiguous 3’s to modify arr[] = {1, 1}. Cost = 12 + 3 * 3 = 21
Step 4: Remove two contiguous 1’s to modify arr[] = {}. Cost = 21 + 2 * 3 = 27
Input: arr[] = {1, 2, 3, 4, 5, 6, 7}, M = 2
Output: 14
方法:可以使用动态编程解决此问题。步骤如下:
- 初始化3D数组dp [] [] [] ,使dp [left] [right] [count] ,其中left和right表示索引[left,right]之间的运算, count是arr [左边的元素数左]具有相同的值的ARR [左]和计数不包括常用3 [左]。
- 现在有以下两个可能的选择:
- 结束序列以删除具有相同值的元素(包括起始元素) (即arr [left] ),然后从下一个元素开始继续。
- 继续序列以在索引[left + 1,right]之间搜索与arr [left]具有相同值的元素(例如index i ),这使我们能够继续序列。
- 从新序列进行递归调用,并继续上一个序列的过程。
- 完成上述所有步骤后,打印最大费用。
下面是上述方法的实现:
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 )