poj2411

链接:点击打开链接

题意:用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

你可能感兴趣的:(poj2411)