题目描述

CE数码公司开发了一种名为自动涂色机(APM)的产品。它能用预定的颜色给一块由不同尺寸且互不覆盖的矩形构成的平板涂色。

为了涂色,APM需要使用一组刷子。每个刷子涂一种不同的颜色C。APM拿起一把有颜色C的刷子,并给所有颜色为C且符合下面限制的矩形涂色:



为了避免颜料渗漏使颜色混合,一个矩形只能在所有紧靠它上方的矩形涂色后,才能涂色。例如图中矩形F必须在C和D涂色后才能涂色。注意,每一个矩形必须立刻涂满,不能只涂一部分。

写一个程序求一个使APM拿起刷子次数最少的涂色方案。注意,如果一把刷子被拿起超过一次,则每一次都必须记入总数中。

【输入】

第一行为矩形的个数N。下面有N行描述了N个矩形。每个矩形有5个整数描述,左上角的y坐标和x坐标,右下角的y坐标和x坐标,以及预定颜色。

颜色号为1到20的整数。

平板的左上角坐标总是(0, 0)。

坐标的范围是0..99。N小于16。

【输出】

拿起刷子的最少次数。

【输入样例】

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

蒟蒻看到这题,先是mengbi,表示不会DP,只能搜索(+剪枝)

这数据竟然过了(n<16)

搜索思路

读入数据,统计颜色,然后每个颜色都试一遍,即把该颜色的且能涂的砖涂上。

下一次涂色不能涂上次涂过的色。涂完了记录结果

这不会超时吗老铁

为了不超时,加了两个剪枝

最优化剪枝:当前涂色次数大于等于当前答案,直接退出(这个好理解吧)

可行性剪枝:如果当前一个砖都没有涂到,直接退出(如果接着搜,会多一个次数,可能还会死循环,,,)

至于判断该砖是否能涂,先预处理,把紧邻该砖上方的砖用数组记录下来,再判断那些砖是否被涂

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<iomanip>
#include<cstdlib>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<vector>
#define ll long long
using namespace std;
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
while(isdigit(ch)) s=s*10+ch-'0',ch=getchar();
return s*w;
}
struct lbq //结构体 a1b1 该砖左上角坐标 a2b2 右下角坐标 x 颜色
{
int a1,b1,a2,b2,x;
}a[20];
int ccmp(lbq a,lbq b)
{
if(a.a1!=b.a1) return a.a1<b.a1;
return a.b1<b.b1;
}
bool d=false;
int de[20];//de数组表示是否有该颜色
int n,m,ans=999,b[20],fk[20][20]; //b数组代表该砖是否被涂
bool OK(int o)
{
for(int i=1;i<=n;i++)
if(fk[o][i]&&!b[i]) return false; //如果i砖下面紧邻o,但i没涂过,返回false
return true;
}
void dfs(int o,int pq,int xx)//o 涂色次数 pq 涂过颜色的砖 xx 上次涂的颜色
{
if(o>=ans) return;//当前涂色次数大于等于当前答案,直接退出
if(pq==n)//涂完了,记录答案
{
ans=o;
return;
}
for(int i=1;i<=m;i++)//枚举颜色
{
int oj=0;//代表现在用这个颜色涂的砖数
if(i!=xx&&de[i])//如果有这个颜色,并且这种颜色上次没用过
{
for(int j=1;j<=n;j++) //涂色
if(!b[j]&&a[j].x==i&&OK(j))
//如果没涂过该砖,并且能涂
b[j]=1,oj++;
else
if(b[j]&&a[j].x==i)
b[j]++;
if(oj>0)
dfs(o+1,pq+oj,i);//如果涂了砖,进行下一步
for(int j=n;j>=1;j--)//回溯一步
if(b[j]==1&&a[j].x==i&&OK(j))
b[j]=0,oj--;
else
if(b[j]>1&&a[j].x==i)
b[j]--;
}
}
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
a[i].a1=read(),a[i].b1=read(),a[i].a2=read(),a[i].b2=read(),a[i].x=read(),
a[i].a1++,a[i].b1++,de[a[i].x]++;//记录颜色
for(int i=1;i<=20;i++)
if(de[i])
m=i; //求最大颜色编号
sort(a+1,a+n+1,ccmp);//按左上角坐标大小从小到大排序(先考虑纵,再考虑横)
for(int i=2;i<=n;i++)
for(int j=i-1;j>=1;j--)//fk[i][j]表示第i个砖是否紧邻上方第j个砖
if(a[i].a1==a[j].a2+1&&((a[i].b1>=a[j].b1&&a[i].b1<=a[j].b2)||(a[i].b2>=a[j].b1&&a[i].b2<=a[j].b2)))
fk[i][j]=1;//如果i砖的最上面紧邻j砖最下面,且两砖横坐标有重叠,即j砖为i砖紧邻上面的砖
dfs(0,0,0);
printf("%d",ans);//结果
return 0;
}

洛谷P1283 平板涂色 &&一本通1445:平板涂色的更多相关文章

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

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

  2. 洛谷P3703 [SDOI2017]树点涂色(LCT,dfn序,线段树,倍增LCA)

    洛谷题目传送门 闲话 这是所有LCT题目中的一个异类. 之所以认为是LCT题目,是因为本题思路的瓶颈就在于如何去维护同颜色的点的集合. 只不过做着做着,感觉后来的思路(dfn序,线段树,LCA)似乎要 ...

  3. 洛谷 P4170 [CQOI2007]涂色

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

  4. 【算法•日更•第三十期】区间动态规划:洛谷P4170 [CQOI2007]涂色题解

    废话不多说,直接上题:  P4170 [CQOI2007]涂色 题目描述 假设你有一条长度为5的木版,初始时没有涂过任何颜色.你希望把它的5个单位长度分别涂上红.绿.蓝.绿.红色,用一个长度为5的字符 ...

  5. 洛谷P1162—填涂颜色

    这应该是是第一次记录洛谷题库里的题目吧: 题目描述 由数字00组成的方阵中,有一任意形状闭合圈,闭合圈由数字11构成,围圈时只走上下左右44个方向.现要求把闭合圈内的所有空间都填写成22.例如:6 \ ...

  6. 【洛谷p2669】【一本通p1100】金币

    (今天高产) 金币[传送门] 洛谷上的算法标签 自我感觉主要靠循环 这道题是2015年NOIp普及组的题,其实还是很简单的.但为什么写这道题呢? 这道题第一次接触是在一本通刷题的时候,当时学循环结构, ...

  7. 【洛谷p1015】【一本通p1309】回文数(noip1999)

    (过了这个题灰常灰常开心) 好像前两道忘记了传送门: 回文数[传送门] 洛谷算法标签: 其实还有高精度 这个题困死在了十六进制,后来想了想,我们在c[i]中存入一个大于十的数之前的程序也可以实现回文( ...

  8. BZOJ2721或洛谷1445 [Violet]樱花

    BZOJ原题链接 洛谷原题链接 其实推导很简单,只不过我太菜了想不到...又双叒叕去看题解 简单写下推导过程. 原方程:\[\dfrac{1}{x} + \dfrac{1}{y} = \dfrac{1 ...

  9. 「SDOI2014」旅行(信息学奥赛一本通 1564)(洛谷 3313)

    题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我 ...

随机推荐

  1. github 码云 chrome文件树形插件

    偶然间看到github有一个树形插件,对于代码层级较多的项目来说体验提升了很多 github的chrome插件 chrome商店: https://chrome.google.com/webstore ...

  2. Java 生态圈知识汇总

    原文地址:github.com/aalansehaiy… 前言 有人认为编程是一门技术活,要有一定的天赋,非天资聪慧者不能及也.其实不然,笔者虽是计算机专业出身,但工作年限并不长,对于技术这碗饭有一些 ...

  3. jquery 全选样例

    代码: $(function(){ $("#checkAllOld").click(function() { $("input[id^='box_old_']" ...

  4. 红黑树之 原理和算法详细介绍(阿里面试-treemap使用了红黑树) 红黑树的时间复杂度是O(lgn) 高度<=2log(n+1)1、X节点左旋-将X右边的子节点变成 父节点 2、X节点右旋-将X左边的子节点变成父节点

    红黑树插入删除 具体参考:红黑树原理以及插入.删除算法 附图例说明   (阿里的高德一直追着问) 或者插入的情况参考:红黑树原理以及插入.删除算法 附图例说明 红黑树与AVL树 红黑树 的时间复杂度 ...

  5. angular 前端路由不生效解决方案

    angular 前端路由不生效解决方案 Intro 最近使用 Angular 为我的活动室预约项目开发一个前后端分离的客户端,在部署上遇到了一个问题,前端路由不生效,这里记录一下.本地开发正常,但是部 ...

  6. Docker是什么、为什么是一种趋势

    Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来.并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响.那么我就不需要专门运送水果的船和专门运 ...

  7. java基础(22):File、递归

    1. File 1.1 IO概述 回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下次再想使用这些数据,可是已经没有了.那怎么办呢?能不能把运算完的数据都保存下来,下次程序 ...

  8. PlayJava Day009

    今日所学: /* 2019.08.19开始学习,此为补档. */ 1.Date工具类: Date date = new Date() ; //当前时间 SimpleDateFormat sdf = n ...

  9. js使用工具将表单封装成json字符串传到后台,js截取字符串(学生笔记)

    <script src="js/jquery.min.js"></script> <script src="https://cdn.boot ...

  10. 如何给HTML页面的文本设置字符和单词间距

    设置字符和单词间距介绍 属性名 单位 描述 letter-spacing px 设置字符间距 word-spacing px 设置单词间距 letter-spacing设置字符间距 letter-sp ...