给出了一块长为m且宽为n的木板,我们需要将该木板分成m * n个正方形,以使断裂成本最小。板的每个边缘的切割成本都将给定。简而言之,我们需要选择这样的切割顺序,以使成本最小化。
例子:
对于上面板,切成正方形的最佳方法是:在上述情况下,最低总成本是42。使用以下步骤进行评估。初始值:Total_cost = 0 Total_cost = Total_cost + edge_cost * total_pieces成本4水平切割成本= 0 + 4 * 1 = 4成本4垂直切割成本= 4 + 4 * 2 = 12成本3垂直切割成本= 12 + 3 * 2 = 18成本2水平切割成本= 18 + 2 * 3 = 24成本2垂直切割成本= 24 + 2 * 3 = 30成本1水平切割成本= 30 + 1 * 4 = 34成本1垂直切割成本= 34 +1 * 4 = 38成本1垂直切割成本= 38 + 1 * 4 = 42
这个问题可以用贪婪的方法解决,如果总成本用S表示,则S = a1w1 + a2w2…+ akwk,其中wi是某条切边的成本,ai是相应的系数,系数ai由总和决定。在切割过程结束时,我们使用wi进行竞争的切割次数。注意,系数的总和始终是恒定的,因此我们希望找到a可获得的a的分布,以使S最小。为此,我们会尽早在最高成本的边上进行切割,这将达到最佳S。如果遇到多个成本相同的边,我们可以先切割其中的任何一条。
下面是使用上述方法的解决方案,首先我们以相反的顺序对切边成本进行排序,然后将它们从较高的成本循环到较低的成本,以构建我们的解决方案。每次我们选择一条边时,对应零件的数量都会增加1,每次乘以相应的边切割成本。
请注意,下面使用了sort方法,将biger()作为第三个参数发送给sort方法以不递增的顺序对数字进行排序,这是库的预定义函数。
C++
// C++ program to divide a board into m*n squares
#include
using namespace std;
// method returns minimum cost to break board into
// m*n squares
int minimumCostOfBreaking(int X[], int Y[], int m, int n)
{
int res = 0;
// sort the horizontal cost in reverse order
sort(X, X + m, greater());
// sort the vertical cost in reverse order
sort(Y, Y + n, greater());
// initialize current width as 1
int hzntl = 1, vert = 1;
// loop untill one or both cost array are processed
int i = 0, j = 0;
while (i < m && j < n)
{
if (X[i] > Y[j])
{
res += X[i] * vert;
// increase current horizontal part count by 1
hzntl++;
i++;
}
else
{
res += Y[j] * hzntl;
// increase current vertical part count by 1
vert++;
j++;
}
}
// loop for horizontal array, if remains
int total = 0;
while (i < m)
total += X[i++];
res += total * vert;
// loop for vertical array, if remains
total = 0;
while (j < n)
total += Y[j++];
res += total * hzntl;
return res;
}
// Driver code to test above methods
int main()
{
int m = 6, n = 4;
int X[m-1] = {2, 1, 3, 1, 4};
int Y[n-1] = {4, 1, 2};
cout << minimumCostOfBreaking(X, Y, m-1, n-1);
return 0;
}
Java
// Java program to divide a
// board into m*n squares
import java.util.Arrays;
import java.util.Collections;
class GFG
{
// method returns minimum cost to break board into
// m*n squares
static int minimumCostOfBreaking(Integer X[], Integer Y[],
int m, int n)
{
int res = 0;
// sort the horizontal cost in reverse order
Arrays.sort(X, Collections.reverseOrder());
// sort the vertical cost in reverse order
Arrays.sort(Y, Collections.reverseOrder());
// initialize current width as 1
int hzntl = 1, vert = 1;
// loop untill one or both
// cost array are processed
int i = 0, j = 0;
while (i < m && j < n)
{
if (X[i] > Y[j])
{
res += X[i] * vert;
// increase current horizontal
// part count by 1
hzntl++;
i++;
}
else
{
res += Y[j] * hzntl;
// increase current vertical
// part count by 1
vert++;
j++;
}
}
// loop for horizontal array,
// if remains
int total = 0;
while (i < m)
total += X[i++];
res += total * vert;
// loop for vertical array,
// if remains
total = 0;
while (j < n)
total += Y[j++];
res += total * hzntl;
return res;
}
// Driver program
public static void main(String arg[])
{
int m = 6, n = 4;
Integer X[] = {2, 1, 3, 1, 4};
Integer Y[] = {4, 1, 2};
System.out.print(minimumCostOfBreaking(X, Y, m-1, n-1));
}
}
// This code is contributed by Anant Agarwal.
Python3
# Python program to divide a board into m*n squares
# Method returns minimum cost to
# break board into m*n squares
def minimumCostOfBreaking(X, Y, m, n):
res = 0
# sort the horizontal cost in reverse order
X.sort(reverse = True)
# sort the vertical cost in reverse order
Y.sort(reverse = True)
# initialize current width as 1
hzntl = 1; vert = 1
# loop untill one or both
# cost array are processed
i = 0; j = 0
while (i < m and j < n):
if (X[i] > Y[j]):
res += X[i] * vert
# increase current horizontal
# part count by 1
hzntl += 1
i += 1
else:
res += Y[j] * hzntl
# increase current vertical
# part count by 1
vert += 1
j += 1
# loop for horizontal array, if remains
total = 0
while (i < m):
total += X[i]
i += 1
res += total * vert
#loop for vertical array, if remains
total = 0
while (j < n):
total += Y[j]
j += 1
res += total * hzntl
return res
# Driver program
m = 6; n = 4
X = [2, 1, 3, 1, 4]
Y = [4, 1, 2]
print(minimumCostOfBreaking(X, Y, m-1, n-1))
# This code is contributed by Anant Agarwal.
C#
// C# program to divide a
// board into m*n squares
using System;
class GFG
{
// method returns minimum cost to break board into
// m*n squares
static int minimumCostOfBreaking(int[] X, int[] Y,
int m, int n)
{
int res = 0;
// sort the horizontal cost in reverse order
Array.Sort(X, new Comparison(
(i1, i2) => i2.CompareTo(i1)));
// sort the vertical cost in reverse order
Array.Sort(Y, new Comparison(
(i1, i2) => i2.CompareTo(i1)));
// initialize current width as 1
int hzntl = 1, vert = 1;
// loop untill one or both
// cost array are processed
int i = 0, j = 0;
while (i < m && j < n)
{
if (X[i] > Y[j])
{
res += X[i] * vert;
// increase current horizontal
// part count by 1
hzntl++;
i++;
}
else
{
res += Y[j] * hzntl;
// increase current vertical
// part count by 1
vert++;
j++;
}
}
// loop for horizontal array,
// if remains
int total = 0;
while (i < m)
total += X[i++];
res += total * vert;
// loop for vertical array,
// if remains
total = 0;
while (j < n)
total += Y[j++];
res += total * hzntl;
return res;
}
// Driver program
public static void Main(String []arg)
{
int m = 6, n = 4;
int []X = {2, 1, 3, 1, 4};
int []Y = {4, 1, 2};
Console.WriteLine(minimumCostOfBreaking(X, Y, m-1, n-1));
}
}
// This code is contributed by Princi Singh
输出:
42