平板涂色

https://loj.ac/problem/10023

题目描述

  有一个矩形,上面有若干的矩形需要涂某一种颜色,并且一个矩形能涂色当且仅当与它的上边直接相接的矩形都已涂完。求刷子最少要换几次颜色。

思路

  看这么小的数据范围想都不用想直接爆搜。我们先预处理出每个矩形涂色之间需要那几个矩形涂色完毕,然后暴力枚举当前涂那个矩形,全部涂完后记录答案。这道题只需要加一个最优性剪枝就可以跑的飞快,判当前换颜色数是否大于(ans)即可。

代码

#include <bits/stdc++.h>
using namespace std;
struct aa
{
    int x1,x2,y1,y2;
    int v;
}a[20];
vector<int> p[20];
int n,vis[30],ans;
bool check(int x)
{
    for(int i=0;i<p[x].size();i++)
        if(!vis[p[x][i]])return 0;
    return 1;
}
void dfs(int x,int s,int last)
{
//    cout<<x<<' '<<s<<' '<<last<<endl;
    if(x>=ans)return ;
    if(s==n)
    {
        ans=min(ans,x);
        return ;
    }
    for(int i=1;i<=n;i++)
        if(!vis[i]&&(check(i)||a[i].y1==0))
        {
            vis[i]=1;
            dfs(x+(last!=a[i].v),s+1,a[i].v);
            vis[i]=0;
        }
}
int main() 
{
    scanf("%d",&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].v);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(i!=j&&a[i].y2==a[j].y1&&!(a[i].x1>=a[j].x2||a[i].x2<=a[j].x1))
                    p[j].push_back(i);
    ans=0x7fffffff;
    dfs(0,0,0);
    printf("%d",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/fangbozhen/p/11760653.html