最大化阵列中矩形的覆盖范围

时间:2014-09-01 13:29:38

标签: computer-science

我的任务如下:

输入:

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美元。

找到最佳的起始矩形,使成本尽可能低。

此示例的解决方案如下:
solution

输出:6美元(转移6棵树的所有权)

输入的最大执行时间为1.0秒     1< n< 150和2< m< 5,000 其中nm是果园的大小

任何帮助将不胜感激! :)

1 个答案:

答案 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;
    }

}