POJ 1691 Painting A Board

题目大意:

墙上有一块区域被分成了n个矩形,每个矩形要涂上各自的颜色。为了保证完美要求这一块区域可以进行涂色的条件是它上方的所有区域都已经涂好颜色,这样就不会有后续的操作影响这块区域的颜色。但是如果两块区域颜色不同就要换涂颜色用的刷子。问最少需要换几次。

解题思路:

区域涂色的大体次序是由拓扑排序决定的,当有多个区域在同一层次时需要枚举这些区域来保证换刷子的次数最小。

下面是代码:

#include <stdio.h>
#include <stdlib.h>

struct node1
{
    int x1,y1,x2,y2,c,status;
} node[100];
int cnt,min1,n,edgecnt;
struct edge1
{
    int u,v,next;
} edge[100];
int head[20];
void addedge(int u,int v)
{
    edge[edgecnt].v=v;
    edge[edgecnt].u=u;
    edge[edgecnt].next=head[u];
    head[u]=edgecnt++;
    node[v].status++;
}
int min(int a,int b)
{
    if(a>b)a=b;
    return a;
}
void dfs(int num,int col)
{
    //printf("%d %d %d\n",num,col,cnt);
    if(num==0)
    {
        min1=min(min1,cnt);
        return ;
    }
    for(int i=0; i<n; i++)
    {
        if(node[i].status==0)
        {
            int p=head[i];
            while(p!=-1)
            {
             node[edge[p].v].status--;
                p=edge[p].next;
            }
            if(col!=node[i].c)cnt++;
            node[i].status=-1;
            dfs(num-1,node[i].c);
            node[i].status=0;
            p=head[i];
            while(p!=-1)
            {
                node[edge[p].v].status++;
                p=edge[p].next;
            }
            if(col!=node[i].c)cnt--;
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
        {
            scanf("%d%d%d%d%d",&node[i].y1,&node[i].x1,&node[i].y2,&node[i].x2,&node[i].c);
            node[i].status=0;
            head[i]=-1;
        }
        edgecnt=0;
        min1=10000000;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                if(node[i].y2==node[j].y1&&!(node[j].x1>node[i].x2||node[i].x1>node[j].x2))
                {
                    addedge(i,j);
                }
            }
        }
        cnt=0;
        dfs(n,-1);
        printf("%d\n",min1);
    }
    return 0;
}

POJ 1691 Painting A Board

时间: 2024-08-27 05:45:15

POJ 1691 Painting A Board的相关文章

POJ 1691 Painting A Board(DFS)

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

[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 rectangle

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 题目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

poj 1691

#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<string.h> #include<algorithm> using namespace std; const int maxn = 15; const int maxm = 20; class node{ public: int lx, ly, rx, ry, color;

poj 动态规划题目列表及总结

此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276,1322, 1414, 1456, 1458, 1609, 1644, 1664, 1690, 1699, 1740(博弈),1742, 1887, 1926(马尔科夫矩阵,求平衡), 1936, 1952, 1953, 1958, 1959, 1962, 1975,

[转] POJ DP问题

列表一:经典题目题号:容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1191,1208, 1276, 1322, 1414, 1456, 1458, 1609, 1644, 1664, 1690, 1699, 1740, 1742, 1887, 1926, 1936, 1952, 1953, 1958, 1959, 1962, 1975, 1989, 2018, 2029, 2039, 2063, 20