POJ2411 Mondriaan's Dream DP

Title:

A n ∗ mn*mnm 's chessboard is filled with1 ∗ 2 1*212 small rectangles, how many kinds of schemes are there in total?

answer:

Getting started with DP. There are only 3 kinds of rectangles in each row:

  1. Horizontal 1 ∗ 2 1*212 rectangle

  2. Vertical 1 ∗ 2 1*212 rectangle, this row is above

  3. Vertical 1 ∗ 2 1*212 rectangle, this row is below

Simple analysis is available, use one mmThe m -bit binary number represents the placement of the rectangle in this row. Where thisbitis0 00 means nothing to do with the next line (1, 3),1 11 means related to the next line (2). F [i] [j] F[i][j]F [ i ] [ j ] means theiiThe placement of i row isjjNumber of plans at j .

对于, and F, [i of - the 1], [k], and F, [i of-the 1], [k]F[i1 ] [ k ] transfer toF [i] [j] F[i][j]The conditions of F [ i ] [ j ] are:

  • k & j = 0 k\&j=0 k&j=0 forkkAll below 1 in k are0 00
  • k ∣ j k|j k j each continuous0 0 in thebinary representation0 is an even number. k ∣ jk|jk j is 1 representing a vertical rectangle, including both 2 and 3. The even number is guaranteed 1.

Which continuous 0 0 in the m-bit binary number can be preprocessed0 is an even number.

Error-prone:

Can't preprocess all at once, because continuous 0 0The number of 0 is related to the number of digits! For example, whenm = 7 m=7m=7 o'clock,0 00 is illegal; but whenm = 8 m=8m=At 8 o'clock, 0 is legal. So readmmAccording tommafter mm size preprocessing.

The preprocessing is also very clever. Use odd oddo d d indicates whether there is an odd number of consecutive0 00 ,cut cutc n t means continuous0 00 is odd or even. If this bit is1 11 o d d ∣ = c n t , c n t = 0 odd|=cnt,cnt=0 odd=cnt,cnt=0 , there is no odd number of consecutive0 0 in theupdate memory0 , willcnt cntc n t initialization; if it is not 1, thencnt ∧ = 1 cnt^{\wedge}=1cnt=1 , which means the current segment of continuous0 0Whether 0 is odd or even. After each bit of the binary is traversed, if the last segment is0 00 , thencnt cntat this timec n t has not updatedodd oddo d d , soodd ∣ cnt = = 1 odd|cnt==1oddcnt==When 1 , it means there are an odd number of consecutive0 00 , otherwise it is legal.

Output F [n] [0] F[n][0]F [ n ] [ 0 ] , notF [n] [m] F[n][m]F[n][m]

AC code:

#include <cstdio>
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <algorithm>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define lep(i,a,b) for(int i=(a);i>=(b);i--) 
#define lepp(i,a,b) for(int i=(a);i>(b);i--)
#define pii pair<int,int>
#define pll pair<long long,long long>
#define mp make_pair
#define pb push_back 
#define fir first
#define sec second
#define All(x) x.begin(),x.end() 
#define ms(a,b) memset(a,b,sizeof(a)) 
#define INF 0x3f3f3f3f
#define INFF 0x3f3f3f3f3f3f3f3f
#define multi int T;scanf("%d",&T);while(T--) 
using namespace std;
typedef long long ll;
typedef double db;
const int N=(1<<11)+5;
const int mod=10007;
const db eps=1e-6;                                                                            
const db pi=acos(-1.0);
int n,m,zero2[N];
ll f[15][N];
int main(){
    #ifndef ONLINE_JUDGE
    freopen("D:\\work\\data.in","r",stdin);
    #endif
    // repp(i,0,1<<11){
    //     int cnt=0,odd=0;
    //     repp(j,0,11){
    //         if(i>>j&1) odd|=cnt,cnt=0;
    //         else cnt^=1;
    //     }
    //     zero2[i]=odd|cnt?0:1;
    // }
    f[0][0]=1;
    while(cin>>n>>m&&n){
        repp(i,0,1<<m){
            int cnt=0,odd=0;
            repp(j,0,m){
                if(i>>j&1) odd|=cnt,cnt=0;
                else cnt^=1;
            }
            zero2[i]=odd|cnt?0:1;
        }
        rep(i,1,n)
            repp(j,0,1<<m){
                f[i][j]=0;
                repp(k,0,1<<m){
                    if((j&k)==0&&zero2[j|k]) f[i][j]+=f[i-1][k];
                }
            }
        cout<<f[n][0]<<endl;
    }    
}

Guess you like

Origin blog.csdn.net/Luowaterbi/article/details/110912952