题意
给出了 n n n 个矩形,且给出了这 n n n 个矩形应该涂上的颜色。每次拿起画笔可以涂整个平面中一样颜色的矩形,且每个矩形上方与它贴合的矩形也都要被涂色它才可以被涂色。问最少要拿起多少次画笔。
思路
看一眼数据非常小,考虑爆搜。
每次记录三个参数,非别是记录上一次画的颜色的 l a s t last last,画了多少个矩形的 c n t cnt cnt,拿起了多少次画笔的 s t e p step step。
用一个最优性剪枝来优化一下。用一个标记数组来记录当前矩形是否被上过颜色,如果被上过颜色就,且不符合题目当中的要求(可以用一个 c h e c k check check 函数来解决),直接不处理。再分情况讨论,如果上一次涂的颜色和当前需要涂的颜色一样,就不计入答案,否则将其计入。
代码
#include<bits/stdc++.h>
using namespace std;
struct node{
int x1,y1,x2,y2;
int color;
}a[1000001];
bool vis[1000001];
int n,ans;
bool check(int x)
{
for(int i=1;i<=n;i++)
if(x!=i&&!vis[i]&&a[i].y2==a[x].y1&&
((a[i].x1>=a[x].x1&&a[i].x1<=a[x].x2)||
(a[i].x2>=a[x].x1&&a[i].x2<=a[x].x2)))
return 0;
return 1;
}
void dfs(int last,int cnt,int step)
{
if(step>=ans) return ;
if(cnt==n) ans=min(step,ans);
for(int i=1;i<=n;i++)
{
if(vis[i]||!check(i))
continue;
if(a[i].color==last)
{
vis[i]=1;
dfs(last,cnt+1,step);
vis[i]=0;
}
else
{
vis[i]=1;
dfs(a[i].color,cnt+1,step+1);
vis[i]=0;
}
}
return ;
}
int main()
{
scanf("%d",&n);ans=n;
for(int i=1;i<=n;i++)
scanf("%d %d %d %d %d",&a[i].y1,&a[i].x1,&a[i].y2,&a[i].x2,&a[i].color);
dfs(0,0,0);
printf("%d",ans);
return 0;
}