信息学奥赛一本通T1445:深搜的剪枝技巧 平板涂色

【题目描述】CE数码公司开发了一种名为自动涂色机(APM)的产品。它能用预定的颜色给一块由不同尺寸且互不覆盖的矩形构成的平板涂色。为了涂色,APM需要使用一组刷子。每个刷子涂一种不同的颜色C。APM拿起一把有颜色C的刷子,并给所有颜色为C且符合下面限制的矩形涂色:为了避免颜料渗漏使颜色混合,一个矩形只能在所有紧靠它上方的矩形涂色后,才能涂色。例如图中矩形F必须在C和D涂色后才能涂色。注意,每一个矩

信息学奥赛一本通T1445:平板涂色

【题目描述】

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。

【输出】

拿起刷子的最少次数。

【输入样例】


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

【源程序】

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
const int MOD = 1E9+7;
const int N = 1000000+5;
const int dx[] = {-1,1,0,0,-1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;

struct Rectangle{
    int x1,y1,x2,y2;
    int color;
}rect[20];
bool vis[20];
bool G[40][40];
int res=15;
bool judge(int x) {
    if(rect[x].x1==0)
        return true;
    for(int i=rect[x].y1+1;i<=rect[x].y2;i++)
        if(G[rect[x].x1][i]==0)
            return false;
    return true;
}
void update(int x,int sta){
    for(int i=rect[x].x1+1;i<=rect[x].x2;i++)
        for(int j=rect[x].y1+1;j<=rect[x].y2;j++)
            G[i][j]=sta;
}
void dfs(int p,int k,int num,int n){//第p块板子刷第k次,累积了num块板子
    if(k>res)//可行性剪枝
        return;
    if(num==n)
        res=min(res,k);

    for(int i=1;i<=n;i++){
        if(!vis[i]&&judge(i)){
            update(i,1);
            vis[i]=true;
            num++;
            if(rect[i].color==rect[p].color)
                dfs(i,k,num,n);
            else{
                k++;
                dfs(i,k,num,n);
                k--;
            }
            update(i,0);
            vis[i]=false;
            num--;
        }
    }
}
int main() {
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d%d%d%d",&rect[i].x1,&rect[i].y1,&rect[i].x2,&rect[i].y2,&rect[i].color);
    dfs(0,0,0,n);
    printf("%d\n",res);
    return 0;
}

 

信息学奥赛一本通T1445:深搜的剪枝技巧 平板涂色 归属于 深搜的剪枝技巧,更多同类题解源程序见:深搜的剪枝技巧 和 平板涂色

0 条评论

请先 登录 后评论
不写代码的码农
轩爸

0 篇文章

作家榜 »

  1. admin 2 文章
  2. 张芳 0 文章
  3. hanna 0 文章
  4. Jason 0 文章
  5. lixiaioqian 0 文章
  6. GeraldWrora 0 文章
  7. 董伟 0 文章
  8. 信奥达人 0 文章