JZYZOJ1386 扑街 状压dp
Posted 鲸头鹳
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JZYZOJ1386 扑街 状压dp相关的知识,希望对你有一定的参考价值。
http://172.20.6.3/Problem_Show.asp?id=1386
有一个W行H列的街道,需要用1*2小砖铺盖,小砖之间互相不能重叠,问有多少种不同的铺法? |
数组f的不往后延伸指的是没有对后面产生影响的时候的状态,此时这一列的砖可横可竖但是横着的砖只是从上一列延伸来的而不会延伸到下一列
我觉得复杂度有点扯但是竟然过了,迷。
代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const int maxn=(1<<11)+10; 9 int n,m; 10 long long f[20][maxn]={};//不往下延伸的情况下填格子为t的方案数 11 void dfs(int k,int st,int z,int next1,int num){/*到第几列,转移到的状态, 12 13 转移到第几行的数,上一行竖着放的有没有占到这一格,上一个的状态*/ 14 if(z>n){ 15 if(!next1)f[k][st]+=f[k-1][num]; 16 return; 17 }int x=st%(1<<z)/(1<<(z-1)),y=1<<(z-1); 18 if(next1){ 19 if(x){dfs(k,st,z+1,0,num+y);} 20 return; 21 } 22 if(x) dfs(k,st,z+1,0,num),dfs(k,st,z+1,1,num+y); 23 else dfs(k,st,z+1,0,num+y); 24 } 25 int main(){ 26 scanf("%d%d",&n,&m); 27 if((n&1)&&(m&1)){printf("%d\n",0);return 0;} 28 int ma=1<<n;ma-=1; 29 for(int i=0;i<=ma;i++){ 30 int t=2,x=i;int next1=0,ff=0; 31 while(x){ 32 if(x%t){ 33 if(next1==1) next1=0; 34 else next1=1; 35 }else if(next1){ff=1;break;} 36 x/=t; 37 }if(!ff)f[1][i]=1; 38 } 39 for(int k=2;k<=m;k++){ 40 for(int i=0;i<=ma;i++){ 41 dfs(k,i,1,0,0); 42 } 43 } 44 printf("%I64d",f[m][ma]); 45 return 0; 46 }
以上是关于JZYZOJ1386 扑街 状压dp的主要内容,如果未能解决你的问题,请参考以下文章
HDU4057 Rescue the Rabbit(AC自动机+状压DP)