给定尺寸为2 * N的矩阵M [] [] ,任务是找到用尺寸为2 * 1的图块填充矩阵的最小成本,使得填充图块的成本等于矩阵元素的总和放置在放置瓦片的单元中,折扣等于这些单元中矩阵元素之间的绝对差。
例子:
Input: M[][] = {{1, 4, 3, 5}, {2, 5, 4, 3}}, N = 4
Output: 18
Explanation:
One of the possible solution is,
Place first tile horizontally at (1, 1) and (1, 2). Cost = (1+4) = 5. Discount = (4 – 1) = 3.
Place second tile horizontally at (1, 3) and (1, 4). Cost = (3+5) = 8. Discount = (5 – 3) = 2.
Place third tile horizontally at (2, 1) and (2, 2). Cost = (2 + 5) = 7. Discount (5 – 2) = 3.
Place fourth tile horizontally at (2, 3) and (2, 4). Cost = (4 + 3) = 7. Discount = (4 – 3) = 1.
Therefore, total cost = (5 + 8 + 7 + 7) = 27. Total discount = (3 + 2 + 3 + 1) = 9. Therefore, actual cost = (27 – 9) = 18, which is the minimum cost in placing all tiles.
Input: M[][] = {{7, 5, 1, 3}, {8, 6, 0, 2}}, N = 4
Output : 20
方法:想法是使用动态编程方法来解决问题,因为该问题类似于平铺问题。可以根据以下观察结果解决给定的问题:
- 将图块放置在矩阵中的总成本等于矩阵中存在的元素的总和。因此,通过最大化折扣,可以使实际成本最小化。
- 在此, dp [i]将2×1的图块放置到矩阵中的第i列之后,存储最小的开销。
- 从一个状态到另一个的过渡将是通过在第i列放置当前瓦片垂直或通过在列我水平放置和(i – 1)中的两行。
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 [],用于存储将贴图放置到第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)