[poj 1691] Painting A Board dfs+拓扑排序

Painting A Board

Time Limit: 1000MS Memory Limit: 10000K

Total Submissions: 3611 Accepted: 1795

Description

The CE digital company has built an Automatic Painting Machine (APM) to paint a flat board fully covered by adjacent non-overlapping rectangles of different sizes each with a predefined color.

To color the board, the APM has access to a set of brushes. Each brush has a distinct color C. The APM picks one brush with color C and paints all possible rectangles having predefined color C with the following restrictions:

To avoid leaking the paints and mixing colors, a rectangle can only be painted if all rectangles immediately above it have already been painted. For example rectangle labeled F in Figure 1 is painted only after rectangles C and D are painted. Note that each rectangle must be painted at once, i.e. partial painting of one rectangle is not allowed.

You are to write a program for APM to paint a given board so that the number of brush pick-ups is minimum. Notice that if one brush is picked up more than once, all pick-ups are counted.

Input

The first line of the input file contains an integer M which is the number of test cases to solve (1 <= M <= 10). For each test case, the first line contains an integer N, the number of rectangles, followed by N lines describing the rectangles. Each rectangle R is specified by 5 integers in one line: the y and x coordinates of the upper left corner of R, the y and x coordinates of the lower right corner of R, followed by the color-code of R.

Note that:

Color-code is an integer in the range of 1 .. 20.
Upper left corner of the board coordinates is always (0,0).
Coordinates are in the range of 0 .. 99.
N is in the range of 1..15.

Output

One line for each test case showing the minimum number of brush pick-ups.

Sample Input

1

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

Sample Output

3

Source

Tehran 1999

题目链接http://poj.org/problem?id=1691

题意

墙上有一面黑板,现划分为多个矩形,每个矩形都要涂上一种预设颜色C。

由于涂色时,颜料会向下流,为了避免处于下方的矩形的颜色与上方流下来的颜料发生混合,要求在对矩形i着色时,处于矩形i上方直接相邻位置的全部矩形都必须已填涂颜色。

在填涂颜色a时,若预设颜色为a的矩形均已着色,或暂时不符合着色要求,则更换新刷子,填涂颜色b。

1、 当对矩形i涂色后,发现矩形i下方的矩形j的预设颜色与矩形i一致,且矩形j上方的全部矩形均已涂色,那么j符合填涂条件,可以用 填涂i的刷子对j填涂,而不必更换新刷子。

2、 若颜色a在之前填涂过,后来填涂了颜色b,现在要重新填涂颜色a,还是要启用新刷子,不能使用之前用于填涂颜色a的刷子。

3、 若颜色a在刚才填涂过,现在要继续填涂颜色a,则无需更换新刷子。

4、 矩形着色不能只着色一部分,当确认对矩形i着色后,矩形i的整个区域将被着色。

思路

1.按照题目的规则–》拓扑排序;在矩形正上方连下方矩形一条边;然后按颜色dfs;

if(rec[x].lx>=rec[y].lx&&rec[x].lx<rec[y].rx) return 1;
    if(rec[x].lx<=rec[y].lx&&rec[x].rx>=rec[y].rx) return 1;
    if(rec[x].rx<=rec[y].rx&&rec[x].rx>rec[y].lx) return 1;

2.dfs(num,col,step)

当col==0时即刚换刷子!

代码

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<vector>
using namespace std;

struct node
{
    int lx,ly,rx,ry;
    int col,r;
    bool flag;
    int lin[15];
    int now;
} rec[33];
int n;
int T;
int minn=20;
bool can(int x,int y)
{
    if(rec[x].lx>=rec[y].lx&&rec[x].lx<rec[y].rx) return 1;
    if(rec[x].lx<=rec[y].lx&&rec[x].rx>=rec[y].rx) return 1;
    if(rec[x].rx<=rec[y].rx&&rec[x].rx>rec[y].lx) return 1;
    return 0;

}
void cut(int x,int y)
{
    for(int i=1;i<=rec[x].now;i++)
    rec[rec[x].lin[i]].r+=y;

}
void dfs(int x,int c,int b)
{

    if(b>=minn) return ;
    if(x==n)
    {
        minn=min(b,minn);
        return ;
    }

    if(c==0)
    {
        for(int i=1;i<=n;i++)
        if(rec[i].r==0&&rec[i].flag==0)
        {
            rec[i].flag=1;
            cut(i,-1);
            dfs(x+1,rec[i].col,b);
            cut(i,1);
            rec[i].flag=0;
        }
    }
    else
    {

        int tag=0;
        for(int i=1;i<=n;i++)
        if(rec[i].col==c&&rec[i].r==0&&rec[i].flag==0)
        {

            tag=1;
            rec[i].flag=1;
            cut(i,-1);
            dfs(x+1,c,b);
            cut(i,1);
            rec[i].flag=0;
        }
        if(!tag) dfs(x,0,b+1);
    }

}
void init()
{
    for(int i=1;i<=n;i++)
    {
        rec[i].now=0;
        rec[i].r=0;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        if(i!=j&&rec[i].ry==rec[j].ly)
        {
            if(can(i,j)==1)
            {
                rec[j].r++;
                rec[i].now++;
                rec[i].lin[rec[i].now]=j;
            }
        }
    }

}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        minn=20;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d%d%d",&rec[i].ly,&rec[i].lx,&rec[i].ry,&rec[i].rx,&rec[i].col);
        }
        init();
        dfs(0,0,1);
        printf("%d\n",minn);
    }

}
时间: 2024-10-18 01:23:23

[poj 1691] Painting A Board dfs+拓扑排序的相关文章

POJ 1691 Painting A Board(DFS)

链接 题意 : 看了好长时间终于看懂题目了,将一个大矩形划分成若干小矩形,告诉你每个小矩形的左上角那个点和右下角那个点的坐标,告诉你这个小矩形要涂的颜色,每个颜色对应一个刷子,问你最少要使用几次刷子.因为你要刷一个矩形之前,必须把这个矩形上方与之直接相邻的所有矩形先刷掉才能刷这个,如果你先用了红色的刷子,然后又用了蓝色的刷子,最后又用了红色的刷子,这算是3次使用而不是两次,样例中,用红色刷B所以D也可以刷了,用蓝色先刷A,然后可以刷C,因为B刷了所以E也可以刷了,最后换刷子把剩下的刷掉,总共三次

POJ 1691 Painting A Board

题目大意: 墙上有一块区域被分成了n个矩形,每个矩形要涂上各自的颜色.为了保证完美要求这一块区域可以进行涂色的条件是它上方的所有区域都已经涂好颜色,这样就不会有后续的操作影响这块区域的颜色.但是如果两块区域颜色不同就要换涂颜色用的刷子.问最少需要换几次. 解题思路: 区域涂色的大体次序是由拓扑排序决定的,当有多个区域在同一层次时需要枚举这些区域来保证换刷子的次数最小. 下面是代码: #include <stdio.h> #include <stdlib.h> struct node

poj 1691 Painting A Board 拓扑序+dfs

题意: 一个木板上被分成了很多区域,每个区域要涂上一种特定的颜色,当涂一个区域的时候,它上方与它有重合部分的区域必须之前要涂好.求最少需要拿几次画笔(拿一次画笔可以涂颜色相同的多个区域). 分析: 上方与它有重合部分的区域必须之前要涂好这个限制可以用拓扑序来描述,每次涂有很多种可以涂的颜色,dfs就可以了.dfs的状态空间维数定为拿笔的次数,每次枚举可以涂的颜色.要注意的是dfs过程中要慎用全局变量..否则每个维度需枚举的东西被下一维改了就跪了... 代码: //poj 1691 //sep9

poj - 1691 - Painting A Board(状态压缩dp)

题意:N(1 <= N <= 15)个矩形,每个矩形要涂上指定的颜色C(1 <= C <= 20),如果给一个矩形涂色,那么与它相邻的上方矩形必须已经涂色,问最少要取几次画笔. 题目链接:http://poj.org/problem?id=1691 -->>状态:dp[S][color] 表示达到状态 S 且最后一次涂色为 color 时的最小取画笔数 状态转移方程:dp[S][color] = min(dp[S][color], dp[sub][i]); 或者 dp[

POJ - 1691 Painting A Board (状态压缩 + 暴力)

题目大意:要将一个大矩形內的所有小矩形涂色,涂色要求,只有该矩形上面的所有矩形都涂色了才可以涂该颜色,换一种填涂的颜色就要花费一点体力值,问填涂完需要花费的最小体力值 解题思路:先处理一下填涂该矩形的前提条件,我用了一个can数组表示填涂该矩形时要满足的状态量 用dp[color][state]表示当前用的颜色是color,填涂的状态为state时所用的最少体力值 然后暴力得出转换和结果 #include<cstdio> #include<cstring> #include<

POJ 2367:Genealogical tree(拓扑排序)

Genealogical tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2738 Accepted: 1838 Special Judge Description The system of Martians' blood relations is confusing enough. Actually, Martians bud when they want and where they want. They ga

POJ 1128 &amp; ZOJ 1083 Frame Stacking (拓扑排序)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=83 http://poj.org/problem?id=1128 Frame Stacking Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4102   Accepted: 1378 Description Consider the following 5 picture frames placed

POJ 题目1691 Painting A Board(DFS)

Painting A Board Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3471   Accepted: 1723 Description The CE digital company has built an Automatic Painting Machine (APM) to paint a flat board fully covered by adjacent non-overlapping recta

HDU3342有向图判圈DFS&amp;&amp;拓扑排序法

HDU3342 Legal or Not 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3342 题目意思:一群大牛互相问问题,大牛有不会的,会被更厉害的大牛解答,更厉害的大牛是会的东西比大牛多,但是有的时候更厉害的大牛会装弱,出来问问题,这样就被大牛解答了.这样就形成了一个圈.题目的意思就是让你在一个有向图里面判断是否存在环.我们可以通过dfs和拓扑排序两种方法. DFS的代码: //Author: xiaowuga #include <bits