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[];
bool d[][],h[];
int n,ans=1e9,color,in[],col[],incol[],rec[]; //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[],tmp2[],tmp3[],cnt,p;
for(int i=;i<=n;++i) tmp1[i]=h[i],tmp3[i]=in[i];
for(int i=;i<=color;++i) tmp2[i]=incol[i]; //用tmp数组保存当前状态
for(int i=;i<=color;++i)
{
cnt=; p=zip;
if(!incol[i]) continue;
while(incol[i]) //一直使用该种颜色直到无法再刷
{
for(int j=;j<=n;++j)
if(h[j]&&col[j]==i){
--incol[i]; h[j]=; ++cnt; p+=<<j; //取出有标记的点
for(int u=;u<=n;++u) //枚举下一层
if(d[j][u]){
--in[u];
if(in[u]==) h[u]=,++incol[col[u]]; //打上标记
}
}
}
dfs(t+,x+cnt,p);
for(int j=;j<=n;++j) h[j]=tmp1[j],in[j]=tmp3[j];
for(int j=;j<=color;++j) incol[j]=tmp2[j]; //当前状态回溯
}
}
int main(){
scanf("%d",&n);
for(int i=;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=;i<=n;++i)
for(int j=;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]=,++in[j]; //建图
for(int i=;i<=n;++i) if(!in[i]) h[i]=,++incol[col[i]];
dfs(,,);
printf("%d",ans);
return ;
}

P1283 平板涂色的更多相关文章

  1. 洛谷P1283 平板涂色 &&一本通1445:平板涂色

    题目描述 CE数码公司开发了一种名为自动涂色机(APM)的产品.它能用预定的颜色给一块由不同尺寸且互不覆盖的矩形构成的平板涂色. 为了涂色,APM需要使用一组刷子.每个刷子涂一种不同的颜色C.APM拿 ...

  2. 【题解】洛谷P1283 平板涂色(搜索+暴力)

    思路 看到n<16 整个坐标<100 肯定想到暴力啊 蒟蒻来一发最简单易懂的题解(因为不会DP哈 首先我们用map数组来存坐标图 注意前面的坐标需要加1 因为输入的是坐标 而我们需要的是格 ...

  3. 题解 P1283 【平板涂色】

    P1283 平板涂色 数据范围也太小了qwq..适合本萌新暴搜 小小的剪枝: 1.用pre预处理出每块矩形上方的矩形,pre[i][0]记录数目(如果数据范围再开大一点,直接1~n枚举判断可能超时qw ...

  4. [暑假集训Day3T3]平板涂色

    同样是搜索经典题. 优化并不多,只需在当前步数已经大于目前答案时剪枝就可以了. 此题重点在于如何判断第k个矩形能不能选. 设矩形i的左上坐标为i(squ[i].upx,squ[i].upy),右下角坐 ...

  5. LuoguP1283 平板涂色(状压DP)

    参考了I_AM_HelloWord的代码,\(f[i][j]\)表示转态\(i\)时最后一刷为\(j\)的最小代价,上面的块可用暴力填涂,注意边界 #include <cstdio> #i ...

  6. 1260: [CQOI2007]涂色paint

    Description 假设你有一条长度为5的木版,初始时没有涂过任何颜色.你希望把它的5个单位长度分别涂上红.绿.蓝.绿.红色,用一个长度为5的字符串表示这个目标:RGBGR. 每次你可以把一段连续 ...

  7. 【BZOJ-1260】涂色paint 区间DP

    1260: [CQOI2007]涂色paint Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 1147  Solved: 698[Submit][Sta ...

  8. 并查集(涂色问题) HDOJ 4056 Draw a Mess

    题目传送门 题意:给出一个200 * 50000的像素点矩阵,执行50000次操作,每次把一个矩形/圆形/菱形/三角形内的像素点涂成指定颜色,问最后每种颜色的数量. 分析:乍一看,很像用线段树成段更新 ...

  9. hdu 4559 涂色游戏(对SG函数的深入理解,推导打SG表)

    提议分析: 1 <= N <= 4747 很明显应该不会有规律的,打表发现真没有 按题意应该分成两种情况考虑,然后求其异或(SG函数性质) (1)找出单独的一个(一列中只有一个) (2)找 ...

随机推荐

  1. CNN中的池化层的理解和实例

    池化操作是利用一个矩阵窗口在输入张量上进行扫描,并且每个窗口中的值通过取最大.取平均或其它的一些操作来减少元素个数.池化窗口由ksize来指定,根据strides的长度来决定移动步长.如果stride ...

  2. 3322.org

    3322.org — Krebs on Security https://krebsonsecurity.com/tag/3322-org/

  3. oracle(三) SQL语句

    1.聚集函数遇到空值时,除count(*)外,都会跳过空值. 2.group by 细化聚集函数的作用对象 3.group by有个原则,就是select后面出面的列,除聚集函数外必须出现在group ...

  4. li设置float后ul无法包裹li问题解决

    解决办法:灰常简单,只需给ul添加样式 ul{ overflow: auto; } 即可

  5. INT_MAX和INT_MIN注意事项

    版权声明:转载请注明出处 http://blog.csdn.net/TwT520Ly https://blog.csdn.net/TwT520Ly/article/details/53038345 I ...

  6. testng入门教程14数据驱动(不同文件)

    数据与test脚本不在同一文件时,下面是数据: package data_driver_two_parts; import org.testng.annotations.DataProvider; p ...

  7. checkBox的使用和事件监听

    直接上代码: <!DOCTYPE html> <html> <head> <title></title> </head> < ...

  8. cheng gong de daima

    /** * Copyright (c) 2012-2016 ebizwindow, Inc. All rights reserved. * * Permission is hereby granted ...

  9. mysql套接字文件

  10. VS2010/MFC编程入门之四十四(MFC常用类:定时器Timer)

    前面一节鸡啄米讲了CTime类和CTimeSpan类的使用,本节继续讲与时间有关的定时器.定时器并不是一个类,主要考虑到,提起时间的话就不能不说定时器,所以就把它放到CTime和CTimeSpan之后 ...