ZOJ Problem Set - 1100 Mondriaan's Dream Python 實(shí)現(xiàn)

動(dòng)態(tài)規(guī)劃題。思路就是暴力搜索,以每層為單位搜索,并且狀態(tài)數(shù)目不多,把每一行的方格壓縮為二進(jìn)制編碼。

Python代碼:


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

import sys

 
H = W = 0

# 保存狀態(tài)轉(zhuǎn)化的結(jié)果

tran = []

 
def dfs(n, _from, to):

    '''計(jì)算出寬度為W的時(shí)候,上下兩層不同的方案數(shù)

    _from表示上層的狀態(tài),to表示下層的狀態(tài)

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

    to中1表示填充(或者說第二層必須想辦法填充)

    0表示未填充(或者說第二層不需要填充或不能填充,因?yàn)樯弦粚右呀?jīng)用豎塊填充了)

    '''

    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

    # 保存各層的遞推結(jié)果

    # b[i][j]表示0到i - 1行全填滿且第i行狀態(tài)為j的所有可能數(shù)目

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

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

    # 假設(shè)存在第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()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容