链接:点击打开链接
题意:用1*2的地砖铺满一个n*m的地面有多少种方法
代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; long long n,m,cur; long long dp[2][1<<15]; int main(){ //轮廓线动态规划,相当于将每一个点看成一个 long long i,j,k,n,m; //状态通过轮廓线进行动态规划 while(scanf("%I64d%I64d",&n,&m)!=EOF&&(n||m)){ if(n*m%2){ puts("0"); continue; } if(n<m) swap(n,m); //为了减少状态 cur=0; dp[cur][(1<<m)-1]=1; for(i=0;i<n;i++){ for(j=0;j<m;j++){ cur^=1; memset(dp[cur],0,sizeof(dp[cur])); for(k=0;k<(1<<m);k++){ if(k&(1<<(m-1))) //上一个轮廓线的首位为1,可以选择不放 dp[cur][(k<<1)^(1<<m)]+=dp[1-cur][k]; if(i&&!(k&(1<<(m-1)))) //不是第一行并且上一个状态首位为0,向上放 dp[cur][(k<<1)^1]+=dp[1-cur][k]; if(j&&(k&(1<<(m-1)))&&!(k&1))//首位为1末尾为0,可以向左方 dp[cur][(k<<1)^(1<<m)^3]+=dp[1-cur][k]; } } } printf("%I64d\n",dp[cur][(1<<m)-1]); } return 0; }
轮廓线动态规划博客:
http://www.cnblogs.com/zjutlitao/p/3525349.html?utm_source=tuicool&utm_medium=referral
http://blog.csdn.net/u013480600/article/details/19499899