SGU 131 Hardwood floor(状压DP)

没啥好说的了,主要是两行一起搜索,每次迭代的前提是pre行的y列已经被填满。

因为1*2砖块填充问题陷入定向思维,一直在处理一行,然后卡了N天啊!!!

 

//SGU 131 Hardwood floor
//状压DP
//by night_watcher

#include<iostream>
#include<cstring>
using namespace std;

#define ll long long

int n,m;
ll  cnt;
ll  dp[11][1<<9];

int f(int i){
    return 1<<i;
}

void dfs(int x,int y,int pre,int now){
    if(y>=m){
        dp[x+1][now]+=cnt;
        return ;
    }
    if(pre&f(y)&&now&f(y)){
        dfs(x,y+1,pre,now);
        return ;
    }
    if(!(pre&f(y))&&!(now&f(y))){
        dfs(x,y,pre|f(y),now|f(y));
        if(y+1<m){
            if(!(pre&f(y+1))){
                dfs(x,y+1,pre|f(y)|f(y+1),now|f(y));
            }
            if(!(now&f(y+1))){
                dfs(x,y+1,pre|f(y),now|f(y)|f(y+1));
            }
            if(!(now&f(y+1))&&!(pre&f(y+1))){
                dfs(x,y+1,pre|f(y)|f(y+1),now|f(y+1));
            }
        }
        return ;
    }
    if(!(pre&f(y))&&now&f(y)){
        if(y+1<m&&!(pre&f(y+1))&&!(now&f(y+1))){
            dfs(x,y+1,pre|f(y)|f(y+1),now|f(y+1));
        }
        return ;
    }
    if(pre&f(y)&&!(now&f(y))){
        dfs(x,y+1,pre,now);
        if(y+1<m&&!(pre&f(y+1))&&!(now&f(y+1))){
            dfs(x,y+1,pre|f(y+1),now|f(y)|f(y+1));
        }
        if(y+1<m&&!(now&f(y+1))){
            dfs(x,y+1,pre,now|f(y)|f(y+1));
        }
        return ;
    }
}


int main(){
    int i,j;
    while(cin>>n>>m){
        int max=1<<m;
        memset(dp,0,sizeof(dp));
        dp[0][max-1]=1;
        for(i=0;i<n;i++){
            for(j=0;j<max;j++){
                if(dp[i][j]){
                    cnt=dp[i][j];
                    dfs(i,0,j,0);
                }
            }
        }
        cout<<dp[n][max-1]<<endl;
    }
    return 0;
}


 

你可能感兴趣的:(搜索,动态规划,状态压缩)