📌  相关文章
📜  最小化在矩阵上放置尺寸为2 * 1的瓷砖的成本

📅  最后修改于: 2021-04-17 18:22:08             🧑  作者: Mango

给定尺寸为2 * N的矩阵M [] [] ,任务是找到用尺寸为2 * 1的图块填充矩阵的最小成本,使得填充图块的成本等于矩阵元素总和放置在放置瓦片的单元中,折扣等于这些单元中矩阵元素之间绝对差

例子:

方法:想法是使用动态编程方法来解决问题,因为该问题类似于平铺问题。可以根据以下观察结果解决给定的问题:

  • 将图块放置在矩阵中的总成本等于矩阵中存在的元素的总和。因此,通过最大化折扣,可以使实际成本最小化。
  • 在此, dp [i]2×1的图块放置到矩阵中的i列之后,存储最小的开销。
  • 从一个状态到另一个的过渡将是通过在第i列放置当前瓦片垂直或通过在列水平放置和(i – 1)中的两行。

请按照以下步骤解决问题:

  • 初始化一个变量,例如origCost,以存储在不打折的情况下对瓷砖定步调的总成本
  • 初始化一个数组,例如dp [],用于存储将贴图放置i列时的最大折扣成本
  • 找到网格中所有元素的总和,并将其存储在origCost中
  • 遍历各列并更新dp [i] = max(dp [i – 1] + abs(M [0] [i] – M [1] [i]),dp [i – 2] + abs(M [ 0] [i – 1] – M [0] [i])+ abs(M [1] [i – 1] – M [1] [i]))
  • 完成上述步骤后,作为结果打印(origCost – dp [N – 1])的值。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the minimum cost
// in placing N tiles in a grid M[][]
void tile_placing(vector > grid, int N)
{
    // Stores the minimum profit
    // after placing i tiles
    int dp[N + 5] = { 0 };
    int orig_cost = 0;
 
    // Traverse the grid[][]
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < N; j++) {
 
            // Update the orig_cost
            orig_cost += grid[i][j];
        }
    }
 
    dp[0] = 0;
    dp[1] = abs(grid[0][0] - grid[1][0]);
 
    // Traverse over the range [2, N]
    for (int i = 2; i <= N; i++) {
 
        // Place tiles horizentally
        // or vertically
        dp[i] = max(
            dp[i - 1]
                + abs(grid[0][i - 1] - grid[1][i - 1]),
            dp[i - 2] + abs(grid[0][i - 2] - grid[0][i - 1])
                + abs(grid[1][i - 2] - grid[1][i - 1]));
    }
 
    // Print the answer
    cout << orig_cost - dp[N];
}
 
// Driver Code
int32_t main()
{
    vector > M
        = { { 7, 5, 1, 3 }, { 8, 6, 0, 2 } };
    int N = M[0].size();
 
    tile_placing(M, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG
{
 
  // Function to find the minimum cost
  // in placing N tiles in a grid M[][]
  static void tile_placing(int[][] grid, int N)
  {
    // Stores the minimum profit
    // after placing i tiles
    int dp[] = new int[N + 5];
    Arrays.fill(dp, 0);
    int orig_cost = 0;
 
    // Traverse the grid[][]
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < N; j++) {
 
        // Update the orig_cost
        orig_cost += grid[i][j];
      }
    }
 
    dp[0] = 0;
    dp[1] = Math.abs(grid[0][0] - grid[1][0]);
 
    // Traverse over the range [2, N]
    for (int i = 2; i <= N; i++) {
 
      // Place tiles horizentally
      // or vertically
      dp[i] = Math.max(
        dp[i - 1]
        + Math.abs(grid[0][i - 1] - grid[1][i - 1]),
        dp[i - 2] + Math.abs(grid[0][i - 2] - grid[0][i - 1])
        + Math.abs(grid[1][i - 2] - grid[1][i - 1]));
    }
 
    // Print the answer
    System.out.println(orig_cost - dp[N]);
  }
 
 
  // Driver Code
  public static void main(String[] args)
  {
    int[][] M
      = { { 7, 5, 1, 3 }, { 8, 6, 0, 2 } };
    int N = M[0].length;
 
    tile_placing(M, N);
  }
}
 
// This code is contributed by sanjoy_62.


Python3
# Python3 program for the above approach
 
# Function to find the minimum cost
# in placing N tiles in a grid M[][]
def tile_placing(grid, N) :
 
    # Stores the minimum profit
    # after placing i tiles
    dp = [0]*(N + 5);
    orig_cost = 0;
 
    # Traverse the grid[][]
    for i in range(2) :
        for j in range(N) :
 
            # Update the orig_cost
            orig_cost += grid[i][j];
    dp[0] = 0;
    dp[1] = abs(grid[0][0] - grid[1][0]);
 
    # Traverse over the range [2, N]
    for i in range(2, N + 1) :
 
        # Place tiles horizentally
        # or vertically
        dp[i] = max(
            dp[i - 1]
                + abs(grid[0][i - 1] - grid[1][i - 1]),
            dp[i - 2] + abs(grid[0][i - 2] - grid[0][i - 1])
                + abs(grid[1][i - 2] - grid[1][i - 1]));
 
    # Print the answer
    print(orig_cost - dp[N],end = "");
 
# Driver Code
if __name__ == "__main__" :
 
    M = [ [ 7, 5, 1, 3 ], [ 8, 6, 0, 2 ] ];
    N = len(M[0]);
 
    tile_placing(M, N);
 
    # This code is contributed by AnkThon


C#
// C# program for the above approach
using System;
class GFG
{
 
  // Function to find the minimum cost
  // in placing N tiles in a grid M[][]
  static void tile_placing(int[,] grid, int N)
  {
     
    // Stores the minimum profit
    // after placing i tiles
    int[] dp = new int[N + 5];
    for (int i = 0; i < N + 5; i++) {
        dp[i] = 0;
    }
     
    int orig_cost = 0;
  
    // Traverse the grid[][]
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < N; j++) {
  
        // Update the orig_cost
        orig_cost += grid[i, j];
      }
    }
  
    dp[0] = 0;
    dp[1] = Math.Abs(grid[0, 0] - grid[1, 0]);
  
    // Traverse over the range [2, N]
    for (int i = 2; i <= N; i++) {
  
      // Place tiles horizentally
      // or vertically
      dp[i] = Math.Max(
        dp[i - 1]
        + Math.Abs(grid[0, i - 1] - grid[1, i - 1]),
        dp[i - 2] + Math.Abs(grid[0, i - 2] - grid[0, i - 1])
        + Math.Abs(grid[1, i - 2] - grid[1, i - 1]));
    }
  
    // Print the answer
    Console.Write(orig_cost - dp[N]);
  }
 
// Driver Code
public static void Main()
{
    int[,] M
      = { { 7, 5, 1, 3 }, { 8, 6, 0, 2 } };
    int N = 4;
  
    tile_placing(M, N);
}
}
 
// This code is contributed by code_hunt.


输出:
20

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