• 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;
    }
    
  • 相关阅读:
    转载:人家编写的程序:「雀神 AI」Suphx
    一千六百万单表建联合索引对查询效率的提升
    索引对单列极值查询的显著性影响(百万级别表单列最值查询 Cost由1405变成3)
    经典SQL问题:Top 10%
    区间查询与等效minus查询
    『科学计算』L0、L1与L2范数_理解
    『Python』__getattr__()特殊方法
    『Json』常用方法记录
    『Pickle』数据结构持久化模块_常用方法记录
    『Re』知识工程作业_主体识别
  • 原文地址:https://www.cnblogs.com/812-xiao-wen/p/11002019.html
Copyright © 2020-2023  润新知