poj 2411 Mondriaan's Dream(状压dp)

Mondriaan's Dream

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>

using namespace std;
int N, M;//棋盘的宽和长
long long dp[15][4096];dp[i][j]用于存储填充i-1列状态为j时,i列可能出现的方法数

void dfs(int i, int j, int state, int next) { //i代表列数,j代表当前位数(也可以说是行数-1,初始时为0)
    //state代表状态数,nex代表下一列出现的状态
    if(j == N) {
        dp[i+1][next] += dp[i][state];
        return;
    }

    if(((1<<j)&state) > 0) { //如果这个位置已经被占用,跳过
        dfs(i, j + 1, state, next);
    }

    if(((1<<j)&state) == 0) { //如果这个位置是空的,尝试放一个左右覆盖1*2的木块
        dfs(i, j + 1, state, next | (1 << j));
    }

    if(j+1<N && ((1<<j)&state) == 0 && ((1<<j+1)&state) ==0 ) { //如果这个位置和下一个位置空的,尝试放一个上下覆盖2*1的木块,而此时要跳过下一个木块
        dfs(i, j + 2, state, next);
        //注意j+1<N
    }
    //return;
}

int main() {
    freopen("data.in", "r", stdin);
    while(cin >> N >> M && N != 0 && M != 0) {//n行m列
        memset(dp, 0, sizeof(dp));

        dp[1][0]=1; //初始化第一列状态为0的方法数等于1
        for(int i = 1; i <= M; i++) { //外层遍历每一列
            for(int j = 0; j < (1<<N); j++) { //内层遍历每一行的各种状态
                if(dp[i][j]) {  //
                    dfs(i, 0, j, 0);//如果方法数不空,就执行dfs
                }
            }
        }

        cout<<dp[M+1][0]<<endl;
    }

    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值