我的任务如下:
输入:
0 0 1 0 0 1 0
0 1 1 1 1 1 0
0 1 1 0 0 1 0
0 1 1 1 1 1 0
0 0 1 0 0 1 0
其中0
表示Apple树,1
表示香蕉树
亚历克斯希望保留所有的苹果树,而贝雷特想要保留香蕉树。 转让树木所有权的成本为1美元。
找到最佳的起始矩形,使成本尽可能低。
此示例的解决方案如下:
输出:6美元(转移6棵树的所有权)
输入的最大执行时间为1.0秒
1< n< 150和2< m< 5,000
其中n
和m
是果园的大小
任何帮助将不胜感激! :)
答案 0 :(得分:0)
除非有关于运行时间或整体方法的特殊要求,否则您可以使用一个相当简单的解决方案:对于每个可能的矩形,检查必须移动多少树。这可以通过4个嵌套的for
循环和一些实用方法来完成。
这是一个MCVE(我没有彻底测试,但它应该显示一般方法)
public class OptimizeRectangle
{
public static void main(String[] args)
{
int array[][] =
{
{ 0, 0, 1, 0, 0, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 0, 0, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 0 },
{ 0, 0, 1, 0, 0, 1, 0 },
};
optimize(array);
}
private static void optimize(int array[][])
{
int rows = array.length;
int cols = array[0].length;
int ones = count(array, 0, 0, rows, cols, 1);
int bestR0 = 0;
int bestC0 = 0;
int bestR1 = 0;
int bestC1 = 0;
int minToMove = Integer.MAX_VALUE;
for (int r0=0; r0<rows; r0++)
{
for (int c0=0; c0<cols; c0++)
{
for (int r1=r0+1; r1<=rows; r1++)
{
for (int c1=c0+1; c1<=cols; c1++)
{
int zerosInRect = count(array, r0, c0, r1, c1, 0);
int onesInRect = count(array, r0, c0, r1, c1, 1);
int toMove =
(ones - onesInRect) + zerosInRect;
if (toMove < minToMove)
{
minToMove = toMove;
bestR0 = r0;
bestC0 = c0;
bestR1 = r1;
bestC1 = c1;
}
}
}
}
}
System.out.println("Input");
System.out.println(toString(array));
int a[][] = copy(array);
set(a, bestR0, bestC0, bestR1, bestC1, -1);
System.out.println("Result");
System.out.println(toString(a));
}
private static String toString(int array[][])
{
int rows = array.length;
int cols = array[0].length;
StringBuilder sb = new StringBuilder();
for (int r=0; r<rows; r++)
{
for (int c=0; c<cols; c++)
{
if (array[r][c] >= 0)
{
sb.append(array[r][c]+" ");
}
else
{
sb.append(" ");
}
}
sb.append("\n");
}
return sb.toString();
}
private static int[][] copy(int array[][])
{
int result[][] = new int[array.length][];
for (int i=0; i<array.length; i++)
{
result[i] = array[i].clone();
}
return result;
}
private static void set(int array[][],
int r0, int c0, int r1, int c1, int value)
{
for (int r=r0; r<r1; r++)
{
for (int c=c0; c<c1; c++)
{
array[r][c] = value;
}
}
}
private static int count(int array[][],
int r0, int c0, int r1, int c1, int value)
{
int count = 0;
for (int r=r0; r<r1; r++)
{
for (int c=c0; c<c1; c++)
{
if (array[r][c] == value)
{
count++;
}
}
}
return count;
}
}