首页 > 其他 > 详细

ch_POJ2411 Mondriaan's Dream

时间:2019-11-08 21:50:16      阅读:61      评论:0      收藏:0      [点我收藏+]

比较巧妙的状压!

需要扩展的一半的为1,其余为0,

上下两行|一下就是横着放的格子

注意预处理与M有关!

本行:i&1

上行:i&1^1

从一行开始,则初始化0行

#include<iostream>
#include<cstdio>

#define ri register int
#define u long long

namespace opt {

    inline u in() {
        u x(0),f(1);
        char s(getchar());
        while(s<0||s>9) {
            if(s==-) f=-1;
            s=getchar();
        }
        while(s>=0&&s<=9) {
            x=(x<<1)+(x<<3)+s-0;
            s=getchar();
        }
        return x*f;
    }

}

using opt::in;

#define NN 5005
#define MO 1000000000

#include<algorithm>
#include<cmath>
#include<cstring>

namespace mainstay {

    u N,M,can[NN],f[2][NN];

    inline void solve() {

        while(1) {
            N=in(),M=in();
            if(!N&&!M) return;
            std::memset(can,0,sizeof(can));
            for(ri i(0); i<(1<<M); ++i) {
                u _now(0);
                for(ri j(0); j<=M-1; ++j) {
                    if((i>>j)&1) can[i]|=_now,_now=0;
                    else _now^=1;
                }
                can[i]|=_now;
            }
            std::memset(f,0,sizeof(f));
            f[0][0]=1;
            for(ri i(1); i<=N; ++i) {
                std::memset(f[i&1],0,sizeof(f[i&1]));
                for(ri j(0); j<(1<<M); ++j) {
                    for(ri k(0); k<(1<<M); ++k) {
                        if(!(j&k)&&!can[k|j]) f[i&1][j]+=f[i&1^1][k];
                    }
                }
            }
            std::cout<<f[N&1][0]<<std::endl;
        }
    }

}

int main() {

    //freopen("x.txt","r",stdin);
    std::ios::sync_with_stdio(false);
    mainstay::solve();

}

 

ch_POJ2411 Mondriaan's Dream

原文:https://www.cnblogs.com/ling-zhi/p/11823084.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!