ZOJ Problem Set - 1100 Mondriaan's Dream Python 实现

动态规划题。思路就是暴力搜索,以每层为单位搜索,并且状态数目不多,把每一行的方格压缩为二进制编码。

Python代码:


# -*- coding: utf-8 -*-

import sys

 
H = W = 0

# 保存状态转化的结果

tran = []

 
def dfs(n, _from, to):

    '''计算出宽度为W的时候,上下两层不同的方案数

    _from表示上层的状态,to表示下层的状态

    _from中1表示填充,0表示未填充

    to中1表示填充(或者说第二层必须想办法填充)

    0表示未填充(或者说第二层不需要填充或不能填充,因为上一层已经用竖块填充了)

    '''

    global W, tran

    if n > W:

        return

    if n == W:

        tran.append((_from, to))

        return

    
    # 水平放置砖块

    dfs(n   2, (_from << 2)   3, (to << 2)   3)

    # 竖直放置砖块

    dfs(n   1, (_from << 1)   1, to << 1)

    # 不放置砖块

    dfs(n   1, _from << 1, (to << 1)   1)

 
def dp():

    global W, H, tran

    # 保存各层的递推结果

    # b[i][j]表示0到i - 1行全填满且第i行状态为j的所有可能数目

    # 迭代求出b[H][(1 << W) - 1]即为答案

    b = [[0 for j in xrange(2048)] for i in xrange(12)]

    # 假设存在第0层,且全部填充1,只有一种情况

    b[0][(1 << W) - 1] = 1

    for i in xrange(H):

        for j in tran:

            b[i   1][j[1]]  = b[i][j[0]]

    print b[H][(1 << W) - 1]

            
def main():

    global W, H, tran

    for line in sys.stdin:

        H, W = [int(a) for a in line.split()]

        if H == W == 0:

            break

        tran = []

        if H < W:

            H, W = W, H

        dfs(0, 0, 0)

        dp()

     
if __name__ == '__main__':

    main()

你可能感兴趣的:(ZOJ Problem Set - 1100 Mondriaan's Dream Python 实现)