一、题目
题目描述
C
E
CE
CE 数码公司开发了一种名为自动涂色机
(
A
P
M
)
(APM)
(APM)的产品。它能用预定的颜色给一块由不同尺寸且互不覆盖的矩形构成的平板涂色。
为了涂色,
A
P
M
APM
APM 需要使用一组刷子。每个刷子蘸了颜色
C
C
C 。
A
P
M
APM
APM 拿起一把蘸有颜色
C
C
C 的刷子,并给所有颜色为
C
C
C 的矩形涂色。请注意,涂色有顺序要求:为了避免颜料渗漏使颜色混合,一个矩形只能在所有紧靠它上方的矩形涂色后,才能涂色。例如图中矩形
F
F
F 必须在
C
C
C 和
D
D
D 涂色后才能涂色。注意,每一个矩形必须立刻涂满,不能只涂一部分。
写一个程序求一个使
A
P
M
APM
APM 拿起刷子次数最少的涂色方案。注意,如果一把刷子被拿起超过一次,则每一次都必须记入总数中。
输入格式
第一行为矩形的个数
N
N
N 。
下面有
N
N
N 行描述了
N
N
N 个矩形。每个矩形有
5
5
5 个整数描述,左上角的
y
y
y 坐标和
x
x
x 坐标,右下角的
y
y
y 坐标和
x
x
x 坐标,以及预定颜色。
输出格式
一行一个整数,表示拿起刷子的最少次数。
样例
样例输入
7
0 0 2 2 1
0 2 1 6 2
2 0 4 2 1
1 2 4 4 2
1 4 3 6 1
4 0 6 4 1
3 4 6 6 2
样例输出
3
数据范围与提示
对于全部数据, 1 ≤ N ≤ 14 1≤N≤14 1≤N≤14,颜色号为 1 1 1 到 20 20 20 的整数。保证平板的左上角坐标总是 ( 0 , 0 ) (0, 0) (0,0) ,坐标的范围是 0 0 0 到 9 9 9 。
二、思路解析
相信你在看到 1 ≤ N ≤ 14 1≤N≤14 1≤N≤14时,便有了这个思路:可以先将这个平板利用位置关系建成一个图,再用 d f s dfs dfs 爆搜。
恭喜你!你想对了!思路
A
C
AC
AC !
具体请看代码
三、实现代码(借鉴的这一篇)
#include <bits/stdc++.h>
using namespace std;
const int N = 25;
struct node {
int xa, xb, ya, yb, color;
} a[N];
vector<int> G[N];
int n, ans = 0x3f3f3f3f;
bool vis[N];
bool check(int u) {
int len = G[u].size();
for (int i = 0; i < G[u].size(); i++) {
if (!vis[G[u][i]])
return 0;
}
return 1;
}//判断
void dfs(int sum, int step, int last) {
if (sum >= ans)
return;//剪枝
if (step == n) {
ans = min(ans, sum);
return;
}//判断边界
for (int i = 1; i <= n; i++) {
if (!vis[i] && (check(i) || !a[i].xa)) {
vis[i] = 1;
dfs(sum + (last != a[i].color), step + 1, a[i].color);
vis[i] = 0;
}
}
}//普通的暴力搜索
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d%d%d%d%d", &a[i].xa, &a[i].ya, &a[i].xb, &a[i].yb, &a[i].color);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if ((i ^ j) && a[i].xa == a[j].xb && !(a[j].yb < a[i].ya || a[j].ya > a[i].yb))
G[i].push_back(j);//建图
ans = 0x3f3f3f3f;
dfs(0, 0, 0);//开始搜索
printf("%d", ans);//输出答案
return 0;
}
完美撒花!★,°:.☆( ̄▽ ̄)/$:.°★ 。