📜  N个连续的绳索问题

📅  最后修改于: 2021-04-29 16:36:45             🧑  作者: Mango

在给定N条绳索的情况下,每条绳索都具有与其相关的长度。一次,只有两条连续的小绳子绑在末端,形成一条大绳子,而形成其总长度的成本却很高。当所有绳索绑在一起形成一条绳索时,找到最低成本。

例子:

方法:本文讨论了类似的问题,其中可以连接任意两条绳索,但是在此问题中,只能连接连续的绳索。这个问题可以通过动态规划的矩阵链乘法技术来解决。

最佳子结构:在第二个示例中,绳索的连接方式为(((10 + 20)+ 30)+ 40)
连接10和20;费用= 30;表达式变为((30 + 30)+ 40)
连接30和30;费用= 90;表达式变为(60 + 40)
连接60和40;成本= 190,我们得到一条绳索
一个简单的解决方案是将括号放在所有可能的位置,然后计算每个细分的费用,并求和为总费用。可以对所有有效的括号序列执行此操作,而最小值将是答案。

因此,当放置括号集时,该问题分为较小大小的子问题。因此,该问题具有最佳的子结构属性,可以使用递归轻松解决。

重叠子问题

因此解决方案如下:

  • 预计算不同间隔的总和以节省计算时间。
  • 如果我们想将{arr [i] arr [i + 1]…arr [k]}和{arr [k + 1] arr [k + 2]…arr [j]}的两个部分连接起来,那么我们的成本将是是

    其中MinCost(i,k)=范围(i,k)中的最小成本,sum(arr [i]至arr [j])=连接(i,k)和(k + 1,j )。我们可以将子问题存储在dp表中,以节省计算时间。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
// Function to return the minimum cost
// to connect the given ropes
int MinCost(int arr[], int n)
{
  
    // dp[i][j] = minimum cost in range (i, j)
    // sum[i][j] = sum of range (i, j)
    int dp[n + 5][n + 5], sum[n + 5][n + 5];
  
    // Initializing the sum table
    memset(sum, 0, sizeof(0));
    for (int i = 0; i < n; i++) {
        int k = arr[i];
        for (int j = i; j < n; j++) {
            if (i == j)
                sum[i][j] = k;
            else {
                k += arr[j];
                sum[i][j] = k;
            }
        }
    }
  
    // Computing minimum cost for all
    // the possible interval (i, j)
    // Left range
    for (int i = n - 1; i >= 0; i--) {
  
        // Right range
        for (int j = i; j < n; j++) {
            dp[i][j] = INT_MAX;
  
            // No cost for a single rope
            if (i == j)
                dp[i][j] = 0;
            else {
                for (int k = i; k < j; k++) {
                    dp[i][j] = min(dp[i][j],
                                   dp[i][k] + dp[k + 1][j]
                                       + sum[i][j]);
                }
            }
        }
    }
  
    return dp[0][n - 1];
}
  
// Driver code
int main()
{
    int arr[] = { 7, 6, 8, 6, 1, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    cout << MinCost(arr, n);
  
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
  
// Function to return the minimum cost
// to connect the given ropes
static int MinCost(int arr[], int n)
{
  
    // dp[i][j] = minimum cost in range (i, j)
    // sum[i][j] = sum of range (i, j)
    int [][]dp = new int[n + 5][n + 5];
    int [][]sum = new int[n + 5][n + 5];
  
    // Initializing the sum table
    //memset(sum, 0, sizeof(0));
    for (int i = 0; i < n; i++) 
    {
        int k = arr[i];
        for (int j = i; j < n; j++)
        {
            if (i == j)
                sum[i][j] = k;
            else 
            {
                k += arr[j];
                sum[i][j] = k;
            }
        }
    }
  
    // Computing minimum cost for all
    // the possible interval (i, j)
    // Left range
    for (int i = n - 1; i >= 0; i--)
    {
  
        // Right range
        for (int j = i; j < n; j++) 
        {
            dp[i][j] = Integer.MAX_VALUE;
  
            // No cost for a single rope
            if (i == j)
                dp[i][j] = 0;
            else 
            {
                for (int k = i; k < j; k++) 
                {
                    dp[i][j] = Math.min(dp[i][j],
                                        dp[i][k] + 
                                        dp[k + 1][j] + 
                                        sum[i][j]);
                }
            }
        }
    }
    return dp[0][n - 1];
}
  
// Driver code
public static void main(String []args)
{
    int arr[] = { 7, 6, 8, 6, 1, 1 };
    int n = arr.length;
  
    System.out.println(MinCost(arr, n));
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 implementation of the approach
   
# Function to return the minimum cost
# to connect the given ropes
def MinCost(arr, n):
      
    # dp[i][j] = minimum cost in range (i, j)
    # sum[i][j] = sum of range (i, j)
    dp = [[0 for i in range(n + 5)] 
             for i in range(n + 5)]
    sum = [[0 for i in range(n + 5)] 
              for i in range(n + 5)]
  
    for i in range(n):
        k = arr[i]
        for j in range(i, n):
            if (i == j):
                sum[i][j] = k
            else:
                k += arr[j]
                sum[i][j] = k
  
    # Computing minimum cost for all
    # the possible interval (i, j)
    # Left range
    for i in range(n - 1, -1, -1):
  
        # Right range
        for j in range(i, n):
            dp[i][j] = 10**9
  
            # No cost for a single rope
            if (i == j):
                dp[i][j] = 0
            else :
                for k in range(i, j):
                    dp[i][j] = min(dp[i][j], dp[i][k] +     
                                   dp[k + 1][j] + sum[i][j])
  
    return dp[0][n - 1]
  
# Driver code
arr = [7, 6, 8, 6, 1, 1]
n = len(arr)
  
print(MinCost(arr, n))
  
# This code is contributed
# by Mohit Kumar


C#
// C# implementation of the approach
using System;
      
class GFG
{
  
// Function to return the minimum cost
// to connect the given ropes
static int MinCost(int []arr, int n)
{
  
    // dp[i,j] = minimum cost in range (i, j)
    // sum[i,j] = sum of range (i, j)
    int [,]dp = new int[n + 5, n + 5];
    int [,]sum = new int[n + 5, n + 5];
  
    // Initializing the sum table
    //memset(sum, 0, sizeof(0));
    for (int i = 0; i < n; i++) 
    {
        int k = arr[i];
        for (int j = i; j < n; j++)
        {
            if (i == j)
                sum[i, j] = k;
            else
            {
                k += arr[j];
                sum[i, j] = k;
            }
        }
    }
  
    // Computing minimum cost for all
    // the possible interval (i, j)
    // Left range
    for (int i = n - 1; i >= 0; i--)
    {
  
        // Right range
        for (int j = i; j < n; j++) 
        {
            dp[i, j] = int.MaxValue;
  
            // No cost for a single rope
            if (i == j)
                dp[i, j] = 0;
            else
            {
                for (int k = i; k < j; k++) 
                {
                    dp[i, j] = Math.Min(dp[i, j],
                                        dp[i, k] + 
                                        dp[k + 1, j] + 
                                        sum[i, j]);
                }
            }
        }
    }
    return dp[0, n - 1];
}
  
// Driver code
public static void Main(String []args)
{
    int []arr = { 7, 6, 8, 6, 1, 1 };
    int n = arr.Length;
  
    Console.WriteLine(MinCost(arr, n));
}
}
  
// This code is contributed by Rajput-Ji


输出:
68