📌  相关文章
📜  最小化成本以通过给定的操作将数组减少到单个元素

📅  最后修改于: 2021-09-06 11:27:56             🧑  作者: Mango

给定一个由N 个整数和一个整数K组成的数组a[] ,任务是通过选择任意一对连续的数组元素并将它们替换为(a[i] + a[i+1])用于成本K * (a[i] + a[i+1])

例子:

天真的方法:
最简单的解决方案是将数组分成两半,对于每个索引并递归计算两半的成本,最后将它们各自的成本相加。
下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
#define inf 10000009
 
// Function to combine the sum of the two halves
int Combine(int a[], int i, int j)
{
    int sum = 0;
 
    // Calculate the sum from i to j
    for (int l = i; l <= j; l++)
        sum += a[l];
 
    return sum;
}
 
// Function to minimize the cost to
// reduce the array to a single element
int minCost(int a[], int i, int j, int k)
{
    if (i >= j)
    {
 
        // Base case
        // If n = 1 or n = 0
        return 0;
    }
 
    // Intialize cost to maximum value
    int best_cost = inf;
 
    // Iterate through all possible indices
    // and find the best index
    // to combine the subproblems
    for (int pos = i; pos < j; pos++)
    {
 
        // Compute left subproblem
        int left = minCost(a, i, pos, k);
 
        // Compute right subproblem
        int right = minCost(a, pos + 1, j, k);
 
        // Calculate the best cost
        best_cost = min(best_cost, left + right +
                                   k * Combine(a, i, j));
    }
 
    // Return the answer
    return best_cost;
}
 
// Driver code
int main()
{
    int n = 4;
    int a[] = { 4, 5, 6, 7 };
    int k = 3;
 
    cout << minCost(a, 0, n - 1, k) << endl;
    return 0;
}
 
// This code is contributed by PrinciRaj1992


Java
// Java Program to implement
// the above approach
import java.io.*;
 
class GFG {
 
    static int inf = 10000009;
 
    // Function to minimize the cost to
    // reduce the array to a single element
    public static int minCost(int a[], int i,
                              int j, int k)
    {
        if (i >= j) {
 
            // Base case
            // If n = 1 or n = 0
            return 0;
        }
 
        // Intialize cost to maximum value
        int best_cost = inf;
 
        // Iterate through all possible indices
        // and find the best index
        // to combine the subproblems
        for (int pos = i; pos < j; pos++) {
 
            // Compute left subproblem
            int left = minCost(a, i, pos, k);
 
            // Compute right subproblem
            int right = minCost(a, pos + 1, j, k);
 
            // Calculate the best  cost
            best_cost = Math.min(
                best_cost,
                left + right + k * Combine(a, i, j));
        }
 
        // Return the answer
        return best_cost;
    }
 
    // Function to combine the sum of the two halves
    public static int Combine(int a[], int i, int j)
    {
        int sum = 0;
 
        // Calculate the sum from i to j
        for (int l = i; l <= j; l++)
            sum += a[l];
 
        return sum;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int n = 4;
        int a[] = { 4, 5, 6, 7 };
        int k = 3;
 
        System.out.println(minCost(a, 0, n - 1, k));
    }
}


Python3
# Python3 Program to implement
# the above approach
inf = 10000009;
 
# Function to minimize the cost to
# reduce the array to a single element
def minCost(a, i, j, k):
    if (i >= j):
       
        # Base case
        # If n = 1 or n = 0
        return 0;
 
    # Intialize cost to maximum value
    best_cost = inf;
 
    # Iterate through all possible indices
    # and find the best index
    # to combine the subproblems
    for pos in range(i, j):
       
        # Compute left subproblem
        left = minCost(a, i, pos, k);
 
        # Compute right subproblem
        right = minCost(a, pos + 1, j, k);
 
        # Calculate the best cost
        best_cost = min(best_cost,
                        left + right +
                        k * Combine(a, i, j));
 
    # Return the answer
    return best_cost;
 
# Function to combine
# the sum of the two halves
def Combine(a, i, j):
    sum = 0;
 
    # Calculate the sum from i to j
    for l in range(i, j + 1):
        sum += a[l];
 
    return sum;
 
# Driver code
if __name__ == '__main__':
    n = 4;
    a = [4, 5, 6, 7];
    k = 3;
 
    print(minCost(a, 0, n - 1, k));
 
# This code is contributed by Amit Katiyar


C#
// C# Program to implement
// the above approach
using System;
class GFG{
 
  static int inf = 10000009;
 
  // Function to minimize the cost to
  // reduce the array to a single element
  public static int minCost(int []a, int i,
                            int j, int k)
  {
    if (i >= j)
    {
 
      // Base case
      // If n = 1 or n = 0
      return 0;
    }
 
    // Intialize cost to maximum value
    int best_cost = inf;
 
    // Iterate through all possible indices
    // and find the best index
    // to combine the subproblems
    for (int pos = i; pos < j; pos++)
    {
 
      // Compute left subproblem
      int left = minCost(a, i, pos, k);
 
      // Compute right subproblem
      int right = minCost(a, pos + 1, j, k);
 
      // Calculate the best  cost
      best_cost = Math.Min(best_cost,
                           left + right +
                           k * Combine(a, i, j));
    }
 
    // Return the answer
    return best_cost;
  }
 
  // Function to combine the sum of the two halves
  public static int Combine(int []a, int i, int j)
  {
    int sum = 0;
 
    // Calculate the sum from i to j
    for (int l = i; l <= j; l++)
      sum += a[l];
 
    return sum;
  }
 
  // Driver code
  public static void Main(String[] args)
  {
    int n = 4;
    int []a = { 4, 5, 6, 7 };
    int k = 3;
 
    Console.WriteLine(minCost(a, 0, n - 1, k));
  }
}
 
// This code is contributed by Rohit_ranjan


Javascript


C++
// C++ program for the above approach
#include 
using namespace std;
 
int inf = 10000000;
 
// Function to generate the cost using
// Prefix Sum Array technique
vector preprocess(vector a, int n)
{
    vector p(n);
    p[0] = a[0];
     
    for(int i = 1; i < n; i++)
    {
        p[i] = p[i - 1] + a[i];
    }
    return p;
}
 
// Function to combine the sum of the
// two subproblems
int Combine(vector p, int i, int j)
{
    if (i == 0)
        return p[j];
    else
        return p[j] - p[i - 1];
}
 
// Function to minimize the cost to
// add the array elements to a single element
int minCost(vector a, int i, int j, int k,
            vector prefix, vector> dp)
{
    if (i >= j)
        return 0;
 
    // Check if the value is
    // already stored in the array
    if (dp[i][j] != -1)
        return dp[i][j];
 
    int best_cost = inf;
    for(int pos = i; pos < j; pos++)
    {
         
        // Compute left subproblem
        int left = minCost(a, i, pos,
                           k, prefix, dp);
 
        // Compute left subproblem
        int right = minCost(a, pos + 1, j,
                            k, prefix, dp);
 
        // Calculate minimum cost
        best_cost = min(best_cost, left + right +
                       (k * Combine(prefix, i, j)));
    }
     
    // Store the answer to
    // avoid recalculation
    return dp[i][j] = best_cost;
}
 
// Driver code   
int main()
{
    int n = 4;
 
    vector a = { 4, 5, 6, 7 };
 
    int k = 3;
 
    // Initialise dp array
    vector> dp;
    dp.resize(n + 1, vector(n + 1));
    for(int i = 0; i < n + 1; i++)
    {
        for(int j = 0; j < n + 1; j++)
        {
            dp[i][j] = -1;
        }
    }
 
    // Preprocessing the array
    vector prefix = preprocess(a, n);
     
    cout << minCost(a, 0, n - 1, k, prefix, dp)
         << endl;
 
    return 0;
}
 
// This code is contributed by divyeshrabadiya07


Java
// Java Program for the above approach
import java.util.*;
public class Main {
 
    static int inf = 10000000;
 
    // Function to minimize the cost to
    // add the array elements to a single element
    public static int minCost(int a[], int i, int j, int k,
                              int[] prefix, int[][] dp)
    {
        if (i >= j)
            return 0;
 
        // Check if the value is
        // already stored in the array
        if (dp[i][j] != -1)
            return dp[i][j];
 
        int best_cost = inf;
        for (int pos = i; pos < j; pos++) {
 
            // Compute left subproblem
            int left = minCost(a, i, pos, k, prefix, dp);
 
            // Compute left subproblem
            int right
                = minCost(a, pos + 1, j, k, prefix, dp);
 
            // Calculate minimum cost
            best_cost = Math.min(
                best_cost,
                left + right + (k * Combine(prefix, i, j)));
        }
 
        // Store the answer to
        // avoid recalculation
        return dp[i][j] = best_cost;
    }
 
    // Function to generate the cost using
    // Prefix Sum Array technique
    public static int[] preprocess(int[] a, int n)
    {
        int p[] = new int[n];
        p[0] = a[0];
        for (int i = 1; i < n; i++)
            p[i] = p[i - 1] + a[i];
        return p;
    }
 
    // Function to combine the sum of the two subproblems
    public static int Combine(int[] p, int i, int j)
    {
        if (i == 0)
            return p[j];
        else
            return p[j] - p[i - 1];
    }
 
    // Driver Code
    public static void main(String args[])
    {
        int n = 4;
 
        int a[] = { 4, 5, 6, 7 };
 
        int k = 3;
 
        // Initialise dp array
        int dp[][] = new int[n + 1][n + 1];
        for (int i[] : dp)
            Arrays.fill(i, -1);
 
        // Preprocessing the array
        int prefix[] = preprocess(a, n);
 
        System.out.println(
            minCost(a, 0, n - 1, k, prefix, dp));
    }
}


Python3
# Python3 program for the above approach
inf = 10000000
 
# Function to minimize the cost to
# add the array elements to a single element
def minCost(a, i, j, k, prefix, dp):
     
    if (i >= j):
        return 0
 
    # Check if the value is
    # already stored in the array
    if (dp[i][j] != -1):
        return dp[i][j]
 
    best_cost = inf
    for pos in range(i, j):
 
        # Compute left subproblem
        left = minCost(a, i, pos,
                       k, prefix, dp)
 
        # Compute left subproblem
        right = minCost(a, pos + 1, j,
                        k, prefix, dp)
 
        # Calculate minimum cost
        best_cost = min(best_cost,
                        left + right +
                          (k * Combine(prefix, i, j)))
 
    # Store the answer to
    # avoid recalculation
    dp[i][j] = best_cost
     
    return dp[i][j]
 
# Function to generate the cost using
# Prefix Sum Array technique
def preprocess(a, n):
     
    p = [0] * n
    p[0] = a[0]
     
    for i in range(1, n):
        p[i] = p[i - 1] + a[i]
         
    return p
 
# Function to combine the sum
# of the two subproblems
def Combine(p, i, j):
     
    if (i == 0):
        return p[j]
    else:
        return p[j] - p[i - 1]
 
# Driver Code
if __name__ == "__main__":
     
    n = 4
    a = [ 4, 5, 6, 7 ]
    k = 3
 
    # Initialise dp array
    dp = [[-1 for x in range (n + 1)]
              for y in range (n + 1)]
 
    # Preprocessing the array
    prefix = preprocess(a, n)
 
    print(minCost(a, 0, n - 1, k, prefix, dp))
 
# This code is contributed by chitranayal


C#
// C# Program for the above approach
using System;
class GFG{
 
  static int inf = 10000000;
 
  // Function to minimize the cost to
  // add the array elements to a single element
  public static int minCost(int []a, int i, int j, int k,
                            int[] prefix, int[,] dp)
  {
    if (i >= j)
      return 0;
 
    // Check if the value is
    // already stored in the array
    if (dp[i, j] != -1)
      return dp[i, j];
 
    int best_cost = inf;
    for (int pos = i; pos < j; pos++)
    {
 
      // Compute left subproblem
      int left = minCost(a, i, pos, k, prefix, dp);
 
      // Compute left subproblem
      int right = minCost(a, pos + 1, j,
                          k, prefix, dp);
 
      // Calculate minimum cost
      best_cost = Math.Min(best_cost, left + right +
                          (k * Combine(prefix, i, j)));
    }
 
    // Store the answer to
    // avoid recalculation
    return dp[i, j] = best_cost;
  }
 
  // Function to generate the cost using
  // Prefix Sum Array technique
  public static int[] preprocess(int[] a, int n)
  {
    int []p = new int[n];
    p[0] = a[0];
    for (int i = 1; i < n; i++)
      p[i] = p[i - 1] + a[i];
    return p;
  }
 
  // Function to combine the sum of the two subproblems
  public static int Combine(int[] p, int i, int j)
  {
    if (i == 0)
      return p[j];
    else
      return p[j] - p[i - 1];
  }
 
  // Driver Code
  public static void Main(String []args)
  {
    int n = 4;
 
    int []a = { 4, 5, 6, 7 };
 
    int k = 3;
 
    // Initialise dp array
    int [,]dp = new int[n + 1, n + 1];
    for(int i = 0; i < n + 1; i++)
    {
      for (int j = 0; j < n + 1; j++)
      {
        dp[i, j] = -1;
      }
    }
    // Preprocessing the array
    int []prefix = preprocess(a, n);
 
    Console.WriteLine(minCost(a, 0, n - 1, k,
                              prefix, dp));
  }
}
 
// This code is contributed by sapnasingh4991


Javascript


输出:

132

时间复杂度: O(2 N )
辅助空间: O(1)

Efficient Approach:优化上面的方法,思路是使用动态规划的概念。请按照以下步骤解决问题:

  • 初始化一个矩阵dp[][]并使得dp[i][j]存储从索引ij的总和。
  • 使用 Prefix Sum 技术计算sum(i, j)
  • 计算两个子问题的总和并用最小值更新成本。
  • 存储在 dp[][] 中并返回。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
int inf = 10000000;
 
// Function to generate the cost using
// Prefix Sum Array technique
vector preprocess(vector a, int n)
{
    vector p(n);
    p[0] = a[0];
     
    for(int i = 1; i < n; i++)
    {
        p[i] = p[i - 1] + a[i];
    }
    return p;
}
 
// Function to combine the sum of the
// two subproblems
int Combine(vector p, int i, int j)
{
    if (i == 0)
        return p[j];
    else
        return p[j] - p[i - 1];
}
 
// Function to minimize the cost to
// add the array elements to a single element
int minCost(vector a, int i, int j, int k,
            vector prefix, vector> dp)
{
    if (i >= j)
        return 0;
 
    // Check if the value is
    // already stored in the array
    if (dp[i][j] != -1)
        return dp[i][j];
 
    int best_cost = inf;
    for(int pos = i; pos < j; pos++)
    {
         
        // Compute left subproblem
        int left = minCost(a, i, pos,
                           k, prefix, dp);
 
        // Compute left subproblem
        int right = minCost(a, pos + 1, j,
                            k, prefix, dp);
 
        // Calculate minimum cost
        best_cost = min(best_cost, left + right +
                       (k * Combine(prefix, i, j)));
    }
     
    // Store the answer to
    // avoid recalculation
    return dp[i][j] = best_cost;
}
 
// Driver code   
int main()
{
    int n = 4;
 
    vector a = { 4, 5, 6, 7 };
 
    int k = 3;
 
    // Initialise dp array
    vector> dp;
    dp.resize(n + 1, vector(n + 1));
    for(int i = 0; i < n + 1; i++)
    {
        for(int j = 0; j < n + 1; j++)
        {
            dp[i][j] = -1;
        }
    }
 
    // Preprocessing the array
    vector prefix = preprocess(a, n);
     
    cout << minCost(a, 0, n - 1, k, prefix, dp)
         << endl;
 
    return 0;
}
 
// This code is contributed by divyeshrabadiya07

Java

// Java Program for the above approach
import java.util.*;
public class Main {
 
    static int inf = 10000000;
 
    // Function to minimize the cost to
    // add the array elements to a single element
    public static int minCost(int a[], int i, int j, int k,
                              int[] prefix, int[][] dp)
    {
        if (i >= j)
            return 0;
 
        // Check if the value is
        // already stored in the array
        if (dp[i][j] != -1)
            return dp[i][j];
 
        int best_cost = inf;
        for (int pos = i; pos < j; pos++) {
 
            // Compute left subproblem
            int left = minCost(a, i, pos, k, prefix, dp);
 
            // Compute left subproblem
            int right
                = minCost(a, pos + 1, j, k, prefix, dp);
 
            // Calculate minimum cost
            best_cost = Math.min(
                best_cost,
                left + right + (k * Combine(prefix, i, j)));
        }
 
        // Store the answer to
        // avoid recalculation
        return dp[i][j] = best_cost;
    }
 
    // Function to generate the cost using
    // Prefix Sum Array technique
    public static int[] preprocess(int[] a, int n)
    {
        int p[] = new int[n];
        p[0] = a[0];
        for (int i = 1; i < n; i++)
            p[i] = p[i - 1] + a[i];
        return p;
    }
 
    // Function to combine the sum of the two subproblems
    public static int Combine(int[] p, int i, int j)
    {
        if (i == 0)
            return p[j];
        else
            return p[j] - p[i - 1];
    }
 
    // Driver Code
    public static void main(String args[])
    {
        int n = 4;
 
        int a[] = { 4, 5, 6, 7 };
 
        int k = 3;
 
        // Initialise dp array
        int dp[][] = new int[n + 1][n + 1];
        for (int i[] : dp)
            Arrays.fill(i, -1);
 
        // Preprocessing the array
        int prefix[] = preprocess(a, n);
 
        System.out.println(
            minCost(a, 0, n - 1, k, prefix, dp));
    }
}

蟒蛇3

# Python3 program for the above approach
inf = 10000000
 
# Function to minimize the cost to
# add the array elements to a single element
def minCost(a, i, j, k, prefix, dp):
     
    if (i >= j):
        return 0
 
    # Check if the value is
    # already stored in the array
    if (dp[i][j] != -1):
        return dp[i][j]
 
    best_cost = inf
    for pos in range(i, j):
 
        # Compute left subproblem
        left = minCost(a, i, pos,
                       k, prefix, dp)
 
        # Compute left subproblem
        right = minCost(a, pos + 1, j,
                        k, prefix, dp)
 
        # Calculate minimum cost
        best_cost = min(best_cost,
                        left + right +
                          (k * Combine(prefix, i, j)))
 
    # Store the answer to
    # avoid recalculation
    dp[i][j] = best_cost
     
    return dp[i][j]
 
# Function to generate the cost using
# Prefix Sum Array technique
def preprocess(a, n):
     
    p = [0] * n
    p[0] = a[0]
     
    for i in range(1, n):
        p[i] = p[i - 1] + a[i]
         
    return p
 
# Function to combine the sum
# of the two subproblems
def Combine(p, i, j):
     
    if (i == 0):
        return p[j]
    else:
        return p[j] - p[i - 1]
 
# Driver Code
if __name__ == "__main__":
     
    n = 4
    a = [ 4, 5, 6, 7 ]
    k = 3
 
    # Initialise dp array
    dp = [[-1 for x in range (n + 1)]
              for y in range (n + 1)]
 
    # Preprocessing the array
    prefix = preprocess(a, n)
 
    print(minCost(a, 0, n - 1, k, prefix, dp))
 
# This code is contributed by chitranayal

C#

// C# Program for the above approach
using System;
class GFG{
 
  static int inf = 10000000;
 
  // Function to minimize the cost to
  // add the array elements to a single element
  public static int minCost(int []a, int i, int j, int k,
                            int[] prefix, int[,] dp)
  {
    if (i >= j)
      return 0;
 
    // Check if the value is
    // already stored in the array
    if (dp[i, j] != -1)
      return dp[i, j];
 
    int best_cost = inf;
    for (int pos = i; pos < j; pos++)
    {
 
      // Compute left subproblem
      int left = minCost(a, i, pos, k, prefix, dp);
 
      // Compute left subproblem
      int right = minCost(a, pos + 1, j,
                          k, prefix, dp);
 
      // Calculate minimum cost
      best_cost = Math.Min(best_cost, left + right +
                          (k * Combine(prefix, i, j)));
    }
 
    // Store the answer to
    // avoid recalculation
    return dp[i, j] = best_cost;
  }
 
  // Function to generate the cost using
  // Prefix Sum Array technique
  public static int[] preprocess(int[] a, int n)
  {
    int []p = new int[n];
    p[0] = a[0];
    for (int i = 1; i < n; i++)
      p[i] = p[i - 1] + a[i];
    return p;
  }
 
  // Function to combine the sum of the two subproblems
  public static int Combine(int[] p, int i, int j)
  {
    if (i == 0)
      return p[j];
    else
      return p[j] - p[i - 1];
  }
 
  // Driver Code
  public static void Main(String []args)
  {
    int n = 4;
 
    int []a = { 4, 5, 6, 7 };
 
    int k = 3;
 
    // Initialise dp array
    int [,]dp = new int[n + 1, n + 1];
    for(int i = 0; i < n + 1; i++)
    {
      for (int j = 0; j < n + 1; j++)
      {
        dp[i, j] = -1;
      }
    }
    // Preprocessing the array
    int []prefix = preprocess(a, n);
 
    Console.WriteLine(minCost(a, 0, n - 1, k,
                              prefix, dp));
  }
}
 
// This code is contributed by sapnasingh4991

Javascript


输出:
132

时间复杂度: O(N 2 )
辅助空间: O(N 2 )

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live