Mondriaan's Dream POJ - 2411 (like pressure dp)

Here is the link (^ _-) ☆

DP [i] [j] denotes the i-th row when the program state number j

In the position (i, j) if we choose to tile sideways, then (i, j), (i, j + 1) will fill in as 1, if the tiles on end, we will (i, j) to fill 0 , the (i + 1, j) fill into one.

And 0 is the next line of state influence, no 1

Enumerate each state to determine the legality

 

Pruning: If the state of the line number is 0, continue directly

//#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]<<"\n";
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/minun/p/11330542.html