最大化从 Array 中移除的元素的相邻元素的乘积之和
给定一个大小为N的数组A[] ,任务是找到该数组可能的最大分数。数组的分数是通过对数组执行以下操作,直到数组的大小大于 2 来计算的:
- 选择一个索引i使得1 < i < N 。
- 将A[i-1] * A[i+1]添加到分数中
- 从数组中删除A[i] 。
例子:
Input: A[] = {1, 2, 3, 4}
Output: 12
Explanation:
In the first operation, select i = 2. The score will be increased by A[1] * A[3] = 2 * 4 = 8. The new array after removing A[2] will be {1, 2, 4}.
In the first operation, select i = 1. The score will be increased by A[0] * A[2] = 1 * 4 = 4. The new array after removing A[2] will be {1, 4}.
Since N <= 2, no more operations are possible.
The total score will be 8 + 4 = 12 which is the maximum over all possible choices.
Input: {1, 55}
Output: 0
Explanation: No valid moves are possible.
方法:给定的问题可以使用基于以下观察的动态规划来解决:
- 考虑一个二维数组,比如dp[][]其中dp[i][j]表示从索引i到j的子数组中的最大可能分数。
- 以递增顺序迭代范围[1, N-1]中长度为len的所有子数组,其中i表示开始, j表示当前长度子数组的结束索引。
- 可以看出,对于从i到j的子数组,除i和j之外的最后一个剩余元素 k 的索引可以在[i+1, j-1]范围内。因此,迭代k的所有可能值。因此,DP关系可以表述如下:
dp[i][j] = max( dp[i][j], dp[i][k] + dp[k][j] + A[i]*A[j]) for all k in range [i+1, j-1]
- 最终答案将是dp[0][N-1]。
下面是上述方法的实现:
C++
// C++ implementation for the above approach
#include
using namespace std;
// Stores the dp state where dp[i][j]
// represents the maximum possible score
// in the subarray from index i to j
int dp[101][101];
// Function to calculate maximum possible
// score using the given operations
int maxMergingScore(int A[], int N)
{
// Iterate through all possible
// lengths of the subarray
for (int len = 1; len < N; ++len) {
// Iterate through all the
// possible starting indices i
// having length len
for (int i = 0; i + len < N; ++i) {
// Stores the rightmost index
// of the current subarray
int j = i + len;
// Initial dp[i][j] will be 0.
dp[i][j] = 0;
// Iterate through all possible
// values of k in range [i+1, j-1]
for (int k = i + 1; k < j; ++k) {
dp[i][j] = max(
dp[i][j],
dp[i][k] + dp[k][j]
+ A[i] * A[j]);
}
}
}
// Return the answer
return dp[0][N - 1];
}
// Driver Code
int main()
{
int N = 4;
int A[] = { 1, 2, 3, 4 };
// Function Call
cout << maxMergingScore(A, N) << endl;
N = 2;
int B[] = { 1, 55 };
// Function Call
cout << maxMergingScore(B, N) << endl;
return 0;
}
Java
// Java program for the above approach
import java.io.*;
class GFG
{
// Stores the dp state where dp[i][j]
// represents the maximum possible score
// in the subarray from index i to j
static int maxMergingScore(int A[], int N)
{
int[][] dp = new int[101][101];
for(int i = 0; i < 101; i++)
{
{
for(int j = 0; j < 101; j++)
dp[i][j] = 0;
}
}
// Iterate through all possible
// lengths of the subarray
for (int len = 1; len < N; ++len) {
// Iterate through all the
// possible starting indices i
// having length len
for (int i = 0; i + len < N; ++i) {
// Stores the rightmost index
// of the current subarray
int j = i + len;
// Initial dp[i][j] will be 0.
dp[i][j] = 0;
// Iterate through all possible
// values of k in range [i+1, j-1]
for (int k = i + 1; k < j; ++k) {
dp[i][j] = Math.max(
dp[i][j],
dp[i][k] + dp[k][j]
+ A[i] * A[j]);
}
}
}
// Return the answer
return dp[0][N - 1];
}
// Driver Code
public static void main(String[] args)
{
int N = 4;
int A[] = { 1, 2, 3, 4 };
// Function Call
System.out.println(maxMergingScore(A, N) );
N = 2;
int B[] = { 1, 55 };
// Function Call
System.out.println(maxMergingScore(B, N) );
}
}
// This code is contributed by dwivediyash
C#
// C# program for the above approach
using System;
public class GFG
{
// Stores the dp state where dp[i][j]
// represents the maximum possible score
// in the subarray from index i to j
static int maxMergingScore(int []A, int N)
{
int[,] dp = new int[101,101];
for(int i = 0; i < 101; i++)
{
{
for(int j = 0; j < 101; j++)
dp[i, j] = 0;
}
}
// Iterate through all possible
// lengths of the subarray
for (int len = 1; len < N; ++len) {
// Iterate through all the
// possible starting indices i
// having length len
for (int i = 0; i + len < N; ++i) {
// Stores the rightmost index
// of the current subarray
int j = i + len;
// Initial dp[i][j] will be 0.
dp[i,j] = 0;
// Iterate through all possible
// values of k in range [i+1, j-1]
for (int k = i + 1; k < j; ++k) {
dp[i,j] = Math.Max(
dp[i,j],
dp[i,k] + dp[k,j]
+ A[i] * A[j]);
}
}
}
// Return the answer
return dp[0,N - 1];
}
// Driver Code
static public void Main (){
int N = 4;
int []A = { 1, 2, 3, 4 };
// Function Call
Console.WriteLine(maxMergingScore(A, N) );
N = 2;
int[] B = { 1, 55 };
// Function Call
Console.WriteLine(maxMergingScore(B, N) );
}
}
// This code is contributed by maddler.
Python3
# Python 3 implementation for the above approach
# Stores the dp state where dp[i][j]
# represents the maximum possible score
# in the subarray from index i to j
# Function to calculate maximum possible
# score using the given operations
def maxMergingScore(A, N):
# Iterate through all possible
# len1gths of the subarray
dp = [[0 for i in range(101)] for j in range(101)]
for len1 in range(1,N,1):
# Iterate through all the
# possible starting indices i
# having len1gth len1
for i in range(0, N - len1, 1):
# Stores the rightmost index
# of the current subarray
j = i + len1
# Initial dp[i][j] will be 0.
dp[i][j] = 0
# Iterate through all possible
# values of k in range [i+1, j-1]
for k in range(i + 1, j, 1):
dp[i][j] = max(dp[i][j],dp[i][k] + dp[k][j] + A[i] * A[j])
# Return the answer
return dp[0][N - 1]
# Driver Code
if __name__ == '__main__':
N = 4
A = [1, 2, 3, 4]
# Function Call
print(maxMergingScore(A, N))
N = 2
B = [1, 55]
# Function Call
print(maxMergingScore(B, N))
# This code is contributed by SURENDRA_GANGWAR.
Javascript
12
0
时间复杂度: O(N 3 )
辅助空间: O(N 2 )