码迷,mamicode.com
首页 > 其他好文 > 详细

JZYZOJ1386 扑街 状压dp

时间:2017-11-05 13:09:23      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:table   span   none   one   top   div   int   size   dfs   

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 }
View Code

 

JZYZOJ1386 扑街 状压dp

标签:table   span   none   one   top   div   int   size   dfs   

原文地址:http://www.cnblogs.com/137shoebills/p/7787027.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!