p1368[扑街]广场铺砖
Posted Shadow
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了p1368[扑街]广场铺砖相关的知识,希望对你有一定的参考价值。
描述 Description
有一个W行H列的街道,需要用1*2小砖铺盖,小砖之间互相不能重叠,问有多少种不同的铺法?
输入格式 Input Format
只有一行2个整数,分别为W和H,(1<=W,H<=11)
输出格式 Output Format
只有1个整数,为所有的铺法数。
样例输入 Sample Input
2 4
样例输出 Sample Output
5
时间限制 Time Limitation
1s
注释 Hint
样例解释
来源 Source
poj 2411
状态压缩的例题详细题解看代码吧:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<string> #define intl long long//记住用long long不用long long只有50分别问我怎么知道的 using namespace std; intl w,h,all; intl f[13][1<<13]; void dfs(intl i,intl s,intl s1,intl s2,intl j)//在第i行第j,第i行的初始状态 //为s,当前状态为s1,i+1行状态为s2 { if(s1==all)//如果第i行已经铺完 { f[i+1][s2]+=f[i][s]; return ; } if(!(s1&(1<<j)))//如果第j位为零,就是讲1左移j位与s1进行运算,看结果是否为零 { dfs(i,s,s1|1<<j,s2|1<<j,j+1);//竖着放一块,将这一行和下一行的第j位变为1 //s1|1<<j就是将1左移j位与s1进行或运算 if(j<w-1&&(!(s1&(1<<j+1))))//如果这一行还剩下多余连个空格则可横着放 //如果在j+1位也为零则在这横放一个,继续搜索第j+2位 dfs(i,s,s1|(1<<j)|(1<<(j+1)),s2,j+2); //s1|(1<<j)|(1<<j+1)相信大家都知道了吧,先把第j为变为一在把j+1位变为一 } else//如果第j为不为零 dfs(i,s,s1,s2&~(1<<j),j+1);//则下一层的状态s2的第j个位置也不为零 } int main() { cin>>w>>h; all=(1<<w)-1; if(w*h&1) { cout<<0<<endl; return 0; } f[1][0]=1; for(int i=1;i<=h;i++) for(int j=0;j<=all;j++) dfs(i,j,j,0,0); cout<<f[h+1][0]<<endl; return 0; } //本文中用到的基本位运算可以参考我的模板博客 //http://www.cnblogs.com/lcyhaha/p/7413455.html //在第25下面的第二个补充专栏简单的写有本文中用到的位运算
以上是关于p1368[扑街]广场铺砖的主要内容,如果未能解决你的问题,请参考以下文章