题意:用2*1的方块将n*m的矩形铺满的方法
思路:轮廓线动态规划的经典题目:从左到右从上到下将矩阵划分成若干个阶段,每个阶段有2^m个节点,每个(i,j)又有:不放,竖着放,横着放三个情况,接下来就是状态转移
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 11; long long d[2][1<<MAXN]; int n,m,cur; void update(int a,int b){ if (b & (1<<m)) d[cur][b^(1<<m)] += d[1-cur][a]; } int main(){ while (scanf("%d%d",&n,&m) != EOF){ if (n < m) swap(n,m); memset(d,0,sizeof(d)); cur = 0; d[0][(1<<m)-1] = 1; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++){ cur ^= 1; memset(d[cur],0,sizeof(d[cur])); for (int k = 0; k < (1<<m); k++){ update(k,k<<1); if (i && !(k&(1<<m-1))) update(k,(k<<1)^(1<<m)^1); if (j && !(k&1)) update(k,(k<<1)^3); } } printf("%lld\n",d[cur][(1<<m)-1]); } return 0; }