• poj 2411 Mondriaan's Dream(状态压缩DP)


    Mondriaan's Dream



    $ solution: $

    这道题 $ wch $ 首先想到的是搜索和状态压缩,因为这道题的方块可以竖着也就是产生一个凸起(这里可以状态压缩),我们可以枚举它i行j列上下端凸起的情况产生的方案数,然后进行合并。但是这种方法需要维护的东西太多了,复杂度也很难预测。所以 $ wch $ 想着忽略上端凸起,直接从第一行开始向下递推,然后只需要用状态研所记录下端竖着的(也就是突出的那一部分)。但是递推倒下一行时仍然很麻烦。

    于是我们采用一个状态压缩DP惯用的套路:预处理。这样我们预处理处每一行的填充方案(可以不填)(竖着的块默认向下突出,这样就没有上端凸起),然后我们用二进制的与或运算可以完成两个凸起和凹陷(凹陷就是哪一个格子没被填)是否契合或者有重叠。然后我们暴力枚举(可以预见每一行的填充方案不会很多,这也是预处理的一大好处)。然后我们最后一行只需要选那个下端没有突出的方案作为答案输出即可。



    $ 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
    ",f[n][0]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    通过API方式查看Azure Sign-ins记录
    定期删除Azure存储账号下N天之前的数据文件-ASM
    定期删除Azure存储账号下N天之前的数据文件-ARM
    使用自定义映像批量创建托管磁盘虚拟机
    CentOS6.9 ARM虚拟机扩容系统磁盘
    Linux小技巧
    mysql数据导到本地
    mac安装pkg 一直“正在验证” 卡着
    idea compare功能 之一次bug修复
    番茄三月账单
  • 原文地址:https://www.cnblogs.com/812-xiao-wen/p/11002019.html
Copyright © 2020-2023  润新知