zoukankan      html  css  js  c++  java
  • Mondriaan's Dream POJ

    这里是链接(^_−)☆

    dp[i][j]表示第i行状态为j时的方案数

    在位置(i, j) 如果我们选择横着贴砖,那么将(i, j), (i, j+1)都填写成1,如果竖着贴砖,我们将(i,j)填写成0,将(i+1, j)填写成1.

    及0是对下一行的状态有影响,1为没有

    枚举每一种状态 判断合法性

    剪枝:如果上一行的状态数为0,直接continue

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<map>
    #include<vector>
    
    #define inf 0x3f3f3f3f
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define sd(x) scanf("%d",&(x))
    #define sl(x) scanf("%lld",&(x))
    #define slf(x) scanf("%lf",&(x))
    #define scs(s) scanf("%s",s)
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define per(i,a,b) for(int i=a;i>=b;i--)
    #define lowbit(x) x&(-x)
    #define ls now<<1
    #define rs now<<1|1
    #define lson l,mid,ls
    #define rson mid+1,r,rs
    #define All L,R
    #define int long long
    
    using namespace std;
    
    const int maxn=1e4+10;
    
    int n,m;
    long long  dp[15][3005];
    
    int Cheek(int now)
    {
        int i=0;
        while(i<m)
        {
            if((now&(1<<i))==0)i++;
            else if(i==m-1||!(now&(1<<(i+1))))return 0;
            else i+=2;
        }
        return 1;
    }
    
    int cheek(int a,int b)
    {
        int i=0;
        while(i<m)
        {
            if((a&(1<<i))==0)
            {
                if((b&(1<<i))==0) return 0;
                else i++;
            }
            else
            {
                if((b&(1<<i))==0) i++;
                else if(i==m-1||!((a & (1<<(i+1)))&&(b&(1<<(i+1))))) return 0;
                else i+=2;
            }
    //        cout<<i<<endl;
        }
        return 1;
    }
    /***
    
    !(((a&(1<<(i+1)))==1) && ((b&(1<<(i+1)))==1))
    
    !((a&(1<<(i+1))) && (b&(1<<(i+1))))
    
                if((b & (1<<i)) == 0) i++;
                else if(i == m-1 || !((a &(1<<(i+1))) && (b &(1<<(i+1)))))
                {
                    return 0;
                }
                else i += 2;
    
    ***/
    
    #undef int
    int main()
    {
    #define int long long
        while(~scanf("%lld%lld",&n,&m))
        {
            if(!n&&!m) return 0;
            if(m>n) swap(n,m);
            int M=(1<<m)-1;
            mem(dp,0);
            rep(i,0,M)
            if(Cheek(i)) dp[0][i]=1;
            rep(i,1,n-1)
            {
                rep(j,0,M)
                {
                    rep(k,0,M)
                    {
                        if(!dp[i-1][j]) continue;
                        if(cheek(j,k)) dp[i][k]+=dp[i-1][j];
                    }
                }
            }
    
            rep(i,0,n-1)
            {
                rep(j,0,M)
                cout<<dp[i][j]<<" ";
                cout<<endl;
            }
            cout<<dp[n-1][(1<<m)-1]<<"
    ";
        }
        return 0;
    }
  • 相关阅读:
    在路上(转)
    我,机器
    梧桐道上
    傅盛:如何快慢“炼”金山?(转)
    [JS]笔记15之客户端存储cookie
    [JS]笔记14之事件委托
    [JS]笔记13之Date对象
    将博客搬至CSDN
    [JS]笔记12之事件机制--事件冒泡和捕获--事件监听--阻止事件传播
    [JS]笔记11之正则表达式
  • 原文地址:https://www.cnblogs.com/minun/p/11330542.html
Copyright © 2011-2022 走看看