SGU131--NYOJ435

参考blog
http://m.blog.csdn.net/blog/u012760629/36927465
http://www.cppblog.com/menrowitianya/archive/2014/06/23/207386.html


sgu131
题意:给你一个n*m的矩形,可以填充1*2或者缺一角的2*2矩形,求填发?

输入:
n,m(n,m<9)

输出:
T

思路:DP+DFS解决,代码大概就是固定模式,先从行开始遍历,每行是一个阶段,对于每一行以及下一行,你可以找出状态转移方程dp[i+1][status2]+=dp[i][status1],因为后面一行的状态必然是累加上前面一行的状态,然后分析对于每一行状态,你必须要用DFS来递归遍历所有情况,因为输入比较小,当前行的每一列的摆放必然会影响下下一行的摆放,所以可以设u1,u2两个变量来判断是否影响。

#include<cstdio>
#include<cstring>
long long dp[11][1<<9];
int n,m,i;


void dfs(int row,int status1,int status2,int u1,int u2)
{
    if (row==m)
    {
        idp (u1==0 && u2==0) dp[i+1][status2]+=dp[i][status1];
        return;
    }
    if (u2==0)
    {
        if (u1==0)
        {
            dfs(row+1,status1<<1,(status2<<1)+1,0,0);
            dfs(row+1,status1<<1,(status2<<1)+1,1,0);
            dfs(row+1,status1<<1,(status2<<1)+1,0,1);
        }
        dfs(row+1,(status1<<1)+1-u1,(status2<<1)+1,0,1);
        dfs(row+1,(status1<<1)+1-u1,(status2<<1)+1,1,1);
    }
    if (u1==0) dfs(row+1,(status1<<1),(status2<<1)+u2,1,1);
    dfs(row+1,(status1<<1)+1-u1,(status2<<1)+u2,0,0);
}




int main()
{
    while(scandp("%d%d",&n,&m)!=EOF)
    {
        //m=n=0;
        memset(dp,0,sizeof(dp));
        if (n<m)
        {
            int t=n;
            n=m;
            m=t;
        }
        dp[0][(1<<m)-1]=1;
        for (i=0; i<n; i++) dfs(0,0,0,0,0);
        printdp("%I64d\n",dp[n][(1<<m)-1]);
    }
    return 0;
}


posted @ 2015-07-17 19:59  __夜风  阅读(175)  评论(0编辑  收藏  举报