标签:style blog http io ar os sp for on
题意:用1*2的小矩形拼成n*m(n,m<=11)的矩阵有多少种方案。
解法:状态压缩,dfs求转移。当前一列的状态确定后,后一列必须用横向的矩形来填补前一列的空白格,所以前一列不为空时,这一列可以选择也为空让下一列来填补,或是本列来个纵向的矩形填补(如果有连续的两个空格的话)。
代码:
/****************************************************** * @author:xiefubao *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <string.h> //freopen ("in.txt" , "r" , stdin); using namespace std; #define eps 1e-8 #define zero(_) (abs(_)<=eps) const double pi=acos(-1.0); typedef long long LL; const int Max=100010; const LL INF=0x3FFFFFFF; LL dp[2][(1<<12)]; int n,m; void dfs(int now,int wei,int st,LL num) { if(wei==m) { dp[now][st]+=num; return ; } dfs(now,wei+1,st,num); if(wei<m-1&&!(st&(1<<wei))&&!(st&(1<<(wei+1)))) dfs(now,wei+2,st|(1<<wei)|(1<<(wei+1)),num); } int main() { while(cin>>n>>m&&n+m) { int now=0; memset(dp,0,sizeof dp); dfs(now,0,0,1); for(int i=1; i<n; i++) { memset(dp[now^1],0,sizeof dp[now]); for(int j=0; j<(1<<m); j++) if(dp[now][j]) dfs(now^1,0,(~j)&((1<<m)-1),dp[now][j]); now^=1; } printf("%I64d\n",dp[now][(1<<m)-1]); } return 0; } /* n*1+((n-1)/2+(n-2)/3)*/
标签:style blog http io ar os sp for on
原文地址:http://blog.csdn.net/xiefubao/article/details/41726865