ZOJ 1100 Mondriaan’s Dream

來源:互聯網
上載者:User

中等難度的DP。鋪磚問題,有組合數學公式。 但是用搜尋+dp的方法更……好吧,也很難做。

研究了一個下午的標程,終於搞懂。把每一層的磚塊壓縮為二進位編碼,搜尋上一層到當前層的狀態轉化是否能夠達到。然後從0到11……11Dp。

void dfs ( int n, int from, int to ) 表示當前從左往右有n塊磚,from表示前n塊磚在這一層的編碼,to表示下一層。修改了一下,使得1表示填滿,0表示空位。標程裡居然是01倒過來寫的,我足足發獃了一個鐘頭。

其他沒什麼好說的,對於當前和下一層,每次放磚塊只有三種可能:兩橫,豎放,豎放不下。橫空就是兩個豎放不下……

 

#include <cstdio>
#include <string>

double b[13][3000];
int tran[20000][2];

int H, W, maxMove, nTran;

void dfs ( int n, int from, int to )
...{
    if ( n > W )
        return;
    if ( n == W )
    ...{
        tran[nTran][0] = from;
        tran[nTran ++][1] = 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 );
}

void dp ()
...{
    memset ( b, 0x00, sizeof ( b ) );
    b[0][( 1 << W ) - 1] = 1;
    int i, j;
    for ( i = 0; i < H; i ++ )
        for ( j = 0; j < nTran; j ++ )
            b[i + 1][tran[j][1]] += b[i][tran[j][0]];
}

int main ()
...{
    freopen ( "in.txt", "r", stdin );
    while ( scanf ( "%d %d", &H, &W ) )
    ...{
        if ( !H )
            break;
        int t;
        if ( H < W )
        ...{
            t = H; H = W; W = t;
        }
        nTran = 0;
        dfs ( 0, 0, 0 );
        //pt ();
        dp ();
        //pb ();
        printf ( "%.0f ", b[H][( 1 << W ) - 1] );
    }
    return 0;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.