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
王晓东《计算机算法设计与分析》