zoukankan      html  css  js  c++  java
  • 【poj2411】Mondriaan's Dream 状态压缩dp

    AC传送门:http://vjudge.net/problem/POJ-2411

    【题目大意】

    有一个W行H列的广场,需要用1*2小砖铺盖,小砖之间互相不能重叠,问有多少种不同的铺法?

    【题解】

    对于每一行有w个位置,所以每一行都有0~2w-1种状态。

    对于当前行的状态s,它是由前一行的状态s’转化过来的,显然,对于该行某个位置j:

    如果前一行该位置为0,那么该位置可以竖放 即 0-> 1

    如果前一行连续两个位置为0,那么这两个连续位置可以横放 即00-> 00

    如果前一行该位置为1,显然该位置不能再放,于是应该把该位置设置为0 ,即1-> 0

    /*************
      poj 2411
      by chty
      2016.11.15
    *************/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<ctime>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define FILE "read"
    #define up(i,j,n)  for(int i=j;i<=n;i++)
    namespace INIT{
    	char buf[1<<15],*fs,*ft;
    	inline char getc() {return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
    	inline int read(){
    		int x=0,f=1;  char ch=getc();
    		while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getc();}
    		while(isdigit(ch))  {x=x*10+ch-'0';  ch=getc();}
    		return x*f;
    	}
    }using namespace INIT;
    int n,m;
    long long f[15][2500];
    void dfs(int i,int s1,int s2,int next){
    	if(next>m)  return;
    	if(next==m)  f[i+1][s2]+=f[i][s1];
    	else if((s2&(1<<next))==0){
    		dfs(i,s1,s2|(1<<next),next+1);
    		if((s2&(1<<(next+1)))==0)  dfs(i,s1,s2,next+2);
    	}
    	else dfs(i,s1,s2&~(1<<next),next+1);
    }
    int main(){
    	freopen(FILE".in","r",stdin);
    	freopen(FILE".out","w",stdout);
    	while(~scanf("%d%d",&n,&m)&&n&&m){
    		memset(f,0,sizeof(f));  f[1][0]=1;
    		up(i,1,n)  up(j,0,(1<<m)-1)  if(f[i][j])  dfs(i,j,j,0);
    		printf("%lld
    ",f[n+1][0]);
    	}
    	return 0;
    }
    


  • 相关阅读:
    Appsacn 定期自动化扫描
    安全扫描工具 AppScan
    安全扫描工具 Netsparker
    Appium环境搭建
    selenium元素定位大全
    浅谈 WebDriver如何应对不同浏览器
    自动化环境搭建
    三次握手四次挥手
    通俗讲解python__new__()方法
    第十三章、元类之控制类的调用过程
  • 原文地址:https://www.cnblogs.com/chty/p/6068113.html
Copyright © 2011-2022 走看看