📌  相关文章
📜  合并List的所有元素的最低成本

📅  最后修改于: 2021-04-22 07:25:07             🧑  作者: Mango

给定一个由N个整数组成的列表,任务是以尽可能小的成本将列表中的所有元素合并为一个。合并规则如下:
选择列表中任何两个相邻元素,其值分别为XY,然后将它们合并为一个值为(X + Y)的元素,总费用为(X + Y)

例子:

方法:可以使用动态编程解决此问题。首先定义dp的状态。 DP [l] [r]将是将子数组arr [l … r]合并为一个的最小开销。
现在,让我们看一下递归关系:

该方法的时间复杂度为O(N 3 ),因为总共有N * N个状态,每个状态通常需要O(N)个时间来求解。

下面是上述方法的实现:

CPP
// C++ implementation of the approach
#include 
using namespace std;
  
#define N 401
  
// To store the states of DP
int dp[N][N];
bool v[N][N];
  
// Function to return the minimum merge cost
int minMergeCost(int i, int j, int* arr)
{
  
    // Base case
    if (i == j)
        return 0;
  
    // If the state has been solved before
    if (v[i][j])
        return dp[i][j];
  
    // Marking the state as solved
    v[i][j] = 1;
    int& x = dp[i][j];
  
    // Reference to dp[i][j]
    x = INT_MAX;
  
    // To store the sum of all the
    // elements in the subarray arr[i...j]
    int tot = 0;
    for (int k = i; k <= j; k++)
        tot += arr[k];
  
    // Loop to iterate the recurrence
    for (int k = i + 1; k <= j; k++) {
        x = min(x, tot + minMergeCost(i, k - 1, arr)
                       + minMergeCost(k, j, arr));
    }
  
    // Returning the solved value
    return x;
}
  
// Driver code
int main()
{
    int arr[] = { 1, 3, 7 };
    int n = sizeof(arr) / sizeof(int);
  
    cout << minMergeCost(0, n - 1, arr);
  
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
  
static final int N = 401;
  
// To store the states of DP
static int [][]dp = new int[N][N];
static boolean [][]v = new boolean[N][N];
  
// Function to return the minimum merge cost
static int minMergeCost(int i, int j, int[] arr)
{
  
    // Base case
    if (i == j)
        return 0;
  
    // If the state has been solved before
    if (v[i][j])
        return dp[i][j];
  
    // Marking the state as solved
    v[i][j] = true;
    int x = dp[i][j];
  
    // Reference to dp[i][j]
    x = Integer.MAX_VALUE;
  
    // To store the sum of all the
    // elements in the subarray arr[i...j]
    int tot = 0;
    for (int k = i; k <= j; k++)
        tot += arr[k];
  
    // Loop to iterate the recurrence
    for (int k = i + 1; k <= j; k++) 
    {
        x = Math.min(x, tot + minMergeCost(i, k - 1, arr)
                    + minMergeCost(k, j, arr));
    }
  
    // Returning the solved value
    return x;
}
  
// Driver code
public static void main(String[] args)
{
    int arr[] = { 1, 3, 7 };
    int n = arr.length;
  
    System.out.print(minMergeCost(0, n - 1, arr));
}
}
  
// This code is contributed by PrinciRaj1992


Python3
# Python3 implementation of the approach
import sys
  
N = 401;
  
# To store the states of DP
dp = [[0 for i in range(N)] for j in range(N)];
v = [[False for i in range(N)] for j in range(N)];
  
# Function to return the minimum merge cost
def minMergeCost(i, j, arr):
  
    # Base case
    if (i == j):
        return 0;
  
    # If the state has been solved before
    if (v[i][j]):
        return dp[i][j];
  
    # Marking the state as solved
    v[i][j] = True;
    x = dp[i][j];
  
    # Reference to dp[i][j]
    x = sys.maxsize;
  
    # To store the sum of all the
    # elements in the subarray arr[i...j]
    tot = 0;
    for k in range(i, j + 1):
        tot += arr[k];
  
    # Loop to iterate the recurrence
    for k in range(i + 1, j + 1):
        x = min(x, tot + minMergeCost(i, k - 1, arr) + \
                minMergeCost(k, j, arr));
      
    # Returning the solved value
    return x;
  
# Driver code
if __name__ == '__main__':
    arr = [ 1, 3, 7 ];
    n = len(arr);
  
    print(minMergeCost(0, n - 1, arr));
  
# This code is contributed by PrinciRaj1992


C#
// C# implementation of the approach
using System;
  
class GFG
{
  
static readonly int N = 401;
  
// To store the states of DP
static int [,]dp = new int[N, N];
static bool [,]v = new bool[N, N];
  
// Function to return the minimum merge cost
static int minMergeCost(int i, int j, int[] arr)
{
  
    // Base case
    if (i == j)
        return 0;
  
    // If the state has been solved before
    if (v[i, j])
        return dp[i, j];
  
    // Marking the state as solved
    v[i, j] = true;
    int x = dp[i, j];
  
    // Reference to dp[i,j]
    x = int.MaxValue;
  
    // To store the sum of all the
    // elements in the subarray arr[i...j]
    int tot = 0;
    for (int k = i; k <= j; k++)
        tot += arr[k];
  
    // Loop to iterate the recurrence
    for (int k = i + 1; k <= j; k++) 
    {
        x = Math.Min(x, tot + minMergeCost(i, k - 1, arr)
                    + minMergeCost(k, j, arr));
    }
  
    // Returning the solved value
    return x;
}
  
// Driver code
public static void Main(String[] args)
{
    int []arr = { 1, 3, 7 };
    int n = arr.Length;
  
    Console.Write(minMergeCost(0, n - 1, arr));
}
}
  
// This code is contributed by 29AjayKumar


输出:
15