算法设计与分析: 5-31 喷漆机器人问题

5-31 喷漆机器人问题


问题描述

F 大学开发出一种喷漆机器人 Rob,能用指定颜色给一块矩形材料喷漆。Rob 每次拿起一种颜色的喷枪,为指定颜色的小矩形区域喷漆。喷漆工艺要求,一个小矩形区域只能在所 有紧靠它上方的矩形区域都喷过漆后,才能开始喷漆,且小矩形区域开始喷漆后必须一次性 喷完,不能只喷一部分。为 Rob 编写一个自动喷漆程序,使 Rob 拿起喷枪的次数最少。

喷漆机器人

对于给定的矩形区域和指定的颜色,计算 Rob 拿起喷枪的最少次数。

数据输入:
第一行有 1 个正整数 n,1≤n≤16,表示小矩形的个数。大矩形坐标系如图所示,左上角点的坐标为(0,0)。颜色编号为正整数。接下来的 n 行,每行 用 5 个整数 y1,x1,y2,x2,c 来表示一个矩形。(x1,y1)和(x2,y2)分别表示小矩形的左上角点坐标 和右下角点坐标,c 表示小矩形的颜色。


Java

package Chapter5HuiSuFa;

import java.util.Scanner;

public class PenQiJiQiRen {

    private static int MAXx = 1000;
    private static int MAXy = 1000;
    private static int MAXn = 100;
    private static int[][] board;
    private static int[] color;
    private static boolean[][] g;
    private static int[][] m;
    private static int[] po2;

    private static int n;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);

        while (true){
            n = input.nextInt();

            MAXn = n+1;
            color = new int[n];
            board = new int[MAXx+1][MAXy+1];
            po2 = new int[MAXn];
            g = new boolean[n][n];
            m = new int[n][1<<n];

            for(int i=0; i<n; i++)
                for(int j=0; j<1<<n; j++)
                    m[i][j] = -1;

            for(int i=0; i<=MAXx; i++)
                for(int j=0; j<=MAXy; j++)
                    board[i][j] = -1;

            po2[0] = 1;
            for(int i=1; i<MAXn; i++)
                po2[i]=po2[i-1]<<1;

            for(int i=0; i<n; i++){
                int x1,y1,x2,y2;
                x1 = input.nextInt();
                y1 = input.nextInt();
                x2 = input.nextInt();
                y2 = input.nextInt();
                color[i] = input.nextInt();
                for(int j=x1; j<x2; j++)
                    for(int k=y1; k<y2; k++)
                        board[j][k] = i;
            }

            for(int i=0; i<MAXx; i++)
                for(int j=0; j<MAXy; j++)
                    if(board[i][j]>=0 && board[i+1][j]>=0 && board[i][j]!=board[i+1][j])
                        g[board[i][j]][board[i+1][j]] = true;

            comp();
        }
    }

    private static void comp(){
        int opt = -1;
        for(int i=0; i<n; i++){
            backtrack(i,po2[n]-1);
            if(opt<0 || opt>m[i][po2[n]-1])
                opt = m[i][po2[n]-1];
        }

        System.out.println(opt);
    }

    private static void backtrack(int r, int p){
        if(m[r][p] >= 0) return;
        for(int i=0; i<n; i++)
            if(i!=r && ((p&po2[i])>0 && g[i][r])){
                m[r][p] = MAXx;
                return;
            }

        int np = p-po2[r];
        if(np == 0) m[r][p]=1;
        else
            for(int i=0; i<n; i++)
                if((np&po2[i]) > 0){
                    backtrack(i,np);
                    int v = m[i][np]+(color[r]==color[i]?0:1);
                    if(m[r][p]<0 || m[r][p]>v) m[r][p]=v;
                }
    }
}

Input & Output

7
0 0 2 2 1
0 2 1 6 2
2 0 4 2 1
1 2 4 3 2
1 3 3 6 1
4 0 6 3 1
3 3 6 6 2
3


13
0 0 3 3 1
0 3 2 4 2
0 4 2 5 1
2 3 5 4 1
2 4 3 5 2
3 4 6 5 2
3 2 4 3 1
3 0 4 2 2
4 0 8 1 3
4 1 5 3 2
5 1 6 4 3
6 1 8 3 1
6 3 8 5 1
5

Reference

王晓东《计算机算法设计与分析》

猜你喜欢

转载自blog.csdn.net/ioio_/article/details/81153506
今日推荐