poj 2411 Mondriaan's Dream (compression state DP)

Mondrian's Dream



\(solution:\)

This question \ (Van \) first thought is search and compressed state, because this question is bristling box can produce a bump (here compressed state), we can enumerate it i row j column of the upper and lower ends program number where protrusions generated and then combined. However, this method requires too much maintenance things, the complexity is difficult to predict. So $ Van $ thinking ignores the upper end of projections, beginning recursive down directly from the first row, then simply use the state Institute record (that is, highlighting that part) of the lower end on end. But still a lot of trouble when recursive fall line.

So we use a conventional compressed state DP routine: pretreatment. Filling scheme (can not fill) (block default vertically downwardly projecting, so that no upper projections), then we can be performed using binary arithmetic and we pretreated with or at each row of projections and two recesses ( depression is a grid which has not been filled) fit or whether there is overlap. Then we enumerate violence (the program can be expected to fill each row will not be many, this is a big advantage pretreatment). Then we just need to choose the last line that did not highlight the lower end of the program can be output as an answer.



\(code:\)

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>

#define ll long long
#define db double
#define mp make_pair
#define rg register int

using namespace std;

int n,m,sx,top;
int tou[2055];
ll f[13][2055];

queue<pair<int,int> > p,q;

struct bian{
    int v,to;
}b[4200005];

inline int qr(){
    char ch; bool sign=0; rg res=0;
    while(!isdigit(ch=getchar()))if(ch=='-')sign=1;
    while(isdigit(ch))res=res*10+(ch^48),ch=getchar();
    return sign?-res:res;
}

inline void dfs(int x,int v){
    if(x>=m){
        b[++top].v=v;
        b[top].to=tou[sx];
        tou[sx]=top;
        return ;
    }
    if(!(sx&(1<<x))){
        dfs(x+1,v|(1<<x));
        if(!(sx&(1<<(x+1)))&&x<m-1){
            dfs(x+2,v);
        }
    }else dfs(x+1,v);
}

int main(){
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    while((n=qr())&&(m=qr())){
        rg nn=1<<m; top=0; q=p;
        memset(f,0,sizeof(f)); f[0][0]=1;
        memset(tou,0,sizeof(tou));
        for(rg i=0;i<nn;++i)
            sx=i, dfs(0,0);
        q.push(mp(0,0));
        while(!q.empty()){
            rg x=q.front().first;
            rg y=q.front().second+1;
            q.pop(); if(y>n)break;
            for(rg i=tou[x];i;i=b[i].to){
                if(!f[y][b[i].v])q.push(mp(b[i].v,y));
                f[y][b[i].v]+=f[y-1][x];
            }
        }printf("%lld\n",f[n][0]);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/812-xiao-wen/p/11002019.html