P1283 平板涂色

Posted kafuuchino

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1283 平板涂色相关的知识,希望对你有一定的参考价值。

P1283 平板涂色

dfs

将矩阵转化为图求解,然后我们发现这是个DAG,于是就可以愉快地跑搜索了。

进行dfs时,我们可以用类似拓扑排序的方法。每次将上面所有矩形都被刷过(入度in[ i ]==0)的满足条件的矩形用h数组打个标记

用incol数组表示目前h数组中有几种颜色,然后枚举可转移状态进行dfs

发现数据n<16,于是我们可以将状态用二进制存起来(0/1表示是否已被刷)进行记忆化搜索

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
inline int _max(int &a,int &b) {return a>b ? a:b;}
inline int _min(int &a,int &b) {return a<b ? a:b;}
struct matr{int x1,y1,x2,y2;}a[18];
bool d[18][18],h[18];
int n,ans=1e9,color,in[18],col[18],incol[22],rec[65538]; //rec:存状态,用作记忆化
inline void dfs(int t,int x,int zip){ //t:拿起刷子最少次数 x:已刷几个格子 zip:当前状态
    if(rec[zip]&&rec[zip]<=t) return ; //记忆化搜索
    else rec[zip]=t;
    if(x==n) {ans=_min(ans,t); return ;} //所有矩形已刷过
    int tmp1[18],tmp2[22],tmp3[18],cnt,p;
    for(int i=1;i<=n;++i) tmp1[i]=h[i],tmp3[i]=in[i];
       for(int i=1;i<=color;++i) tmp2[i]=incol[i]; //用tmp数组保存当前状态
    for(int i=1;i<=color;++i)
    {
        cnt=0; p=zip;
        if(!incol[i]) continue;
        while(incol[i]) //一直使用该种颜色直到无法再刷
        {
            for(int j=1;j<=n;++j)
                if(h[j]&&col[j]==i){
                    --incol[i]; h[j]=0; ++cnt; p+=1<<j; //取出有标记的点
                    for(int u=1;u<=n;++u) //枚举下一层
                        if(d[j][u]){
                            --in[u];
                            if(in[u]==0) h[u]=1,++incol[col[u]]; //打上标记
                        }
                }
        }
        dfs(t+1,x+cnt,p);
        for(int j=1;j<=n;++j) h[j]=tmp1[j],in[j]=tmp3[j];
        for(int j=1;j<=color;++j) incol[j]=tmp2[j]; //当前状态回溯
    }
}
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,&col[i]);
        color=_max(color,col[i]);
    }
    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)
                d[i][j]=1,++in[j]; //建图
    for(int i=1;i<=n;++i) if(!in[i]) h[i]=1,++incol[col[i]];
    dfs(0,0,0);
    printf("%d",ans);
    return 0;
}

 

以上是关于P1283 平板涂色的主要内容,如果未能解决你的问题,请参考以下文章

P1283 平板涂色

[算法小练][图][拓扑排序+深度优先搜索] 平板涂色问题

平板涂色

POJ1691平板涂色

平板涂色

#10023. 「一本通 1.3 练习 2」平板涂色