给定一个由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[左侧的元素数left]与arr[ left]具有相同的值,并且计数不包括arr[left] 。
- 现在有以下两种可能的选择:
- 结束序列以移除具有相同值的元素,包括起始元素(即arr[left] ),然后从下一个元素开始继续。
- 继续序列以在索引[left + 1, right]之间搜索与arr[left]具有相同值的元素(比如索引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
Javascript
27
时间复杂度: O(N 4 )
辅助空间: O(N 3 )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。