HDU 4012 Paint on a Wall(BFS+位压缩)(好题)(初遇位压缩)

题意:这题的意思有一个2*n的矩形,要给这个矩形涂色每次可以涂一个矩形形状的某种颜色,允许新颜色覆盖旧的颜色求最少多少步可以求出。(1<=n<=8)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4012

准备拿这题学位压缩,结果看不懂题解...,然后一气之下去学状压dp...才看懂了什么是位压缩,才看懂了这题的题解,然后自己码出来了,一题好题就这么被我水掉了...

思路:每次涂色以后必有一个格子的颜色是最终的颜色,否则这次涂色根本没意义,所以我们把每次涂色后哪些格子成为最终颜色的所有可能都入队,入队的元素是一个struct包含步数和最终颜色已确定的木块集合,这个集合必须用整数表示,所以用到状态压缩,因为最多只有16个格子,所以用16位的二进制来表示,1,表示此格子已是最终颜色,0,表示仍待涂色。

#include
#include
#include
#include
#include
using namespace std;
struct node
{
    int step,cur;
};
int len;
bool flag[1<<16]; //  记录哪些格子已是最终颜色
char str[20];
int bfs()
{
    memset(flag,0,sizeof(flag));
    queueque;
    node start={0,0};
    que.push(start);
    flag[0]=true;
    while(!que.empty()){
        node now=que.front();
        que.pop();
        if(now.cur==(1<<2*len)-1) return now.step; //颜色已涂满所有格子
        node next;
        next.step=now.step+1;
        for(int i=0;i<2*len;i++){  //遍历这个图,找个起点开始涂色
            int tmp=0;
            if((1<=(i/len)*len;j--){ //单行向左扩展,下界的确定是技巧
                if((1<=len) continue;  //双行扩展,只要对某一行的点遍历作为起点即可
            if((1<<(i+len))&now.cur) continue; //易错,这个起点的另一行对应的起点如果已是最终颜色,continue
            tmp=0; 
            for(int j=i;j=0;j--){
                if((1<



你可能感兴趣的:(BFS,位压缩)