• POJ #2411


    Good reference: http://www.cppblog.com/sdfond/archive/2009/07/31/91761.html

    It is a classic coveragedp compression problem. Initially I thought of dp[i][j] (i is row, j is col), but looks like it was not feasible to have a good dp transition function. Instead, the correct way to have dp[i][j] is: i is row still, but j is the state - state is binary representation which is said to be compressed (please check url above). It is just not that easy to figure out the key idea: valid state transition from row i to row i + 1.

    First, a recursion procedure is used to compose all valid state transitions - bits by bits. And keep the transition restrictions in mind, we add two more full-state rows: row(0) and row(n+1) to make sure no tile exceeds the limit. At last, we pick row(n+1)(all-1-full-state)'s value which indicates a final valid state. And each dp move means a solution count accumulation.

    Really interesting dp problem. And here is the AC code - since i'm still rookie, i just retyped almost everything in the url above :P

    //    POJ 2411
    //    http://www.cppblog.com/sdfond/archive/2009/07/31/91761.html
    
    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    #define MAX_N 11
    #define MAX_SIZE (1 << MAX_N)
    typedef unsigned long long uint64_t;
    
    vector<unsigned> rec[MAX_SIZE];    // s2 -> [s1]: for a dest state s2, recording all its previous valid s1 states
    uint64_t dp[MAX_N + 2][MAX_SIZE];
    
    //    Compose all valid s1->s2 transition by making composing every move valid
    //    Note: a pattern of combinations by recurrence
    void dfs(int col, int s1, int s2, int w, uint64_t MaxState)
    {
        if (col >= w)
        {
            if (s1 <= MaxState && s2 <= MaxState)
                rec[s2].push_back(s1);    //    S1->S2 is a valid transition
            return;
        }
    
        dfs(col + 1, (s1 << 1) | 1, s2 << 1, w, MaxState);
        dfs(col + 1, s1 << 1, (s2 << 1) | 1, w, MaxState);
        dfs(col + 2, (s1 << 2) | 3, (s2 << 2) | 3, w, MaxState);
    }
    
    uint64_t calc(int h, int w)
    {
        uint64_t MaxState = (1 << w) - 1;
    
        //    Reset rec
        for (int i = 0; i <= MaxState; i ++)
            rec[i].clear();
    
        //    DFS precalc - all valid state transitions
        dfs(0, 0, 0, w, MaxState);
    
        //    Go DP
        dp[0][0] = 1;    // row 0 added to start with
        for (int i = 1; i <= h + 1; i++)    //    each row
        for (uint64_t s = 0; s <= MaxState; s ++)    // each state
        for (int k = 0; k < rec[s].size(); k ++)
        {
            dp[i][s] += dp[i - 1][rec[s][k]];
        }
        return dp[h+1][MaxState];
    }
    
    int main()
    {
        int w, h;
        while (scanf("%d %d", &h, &w), h && w)
        {
            if (h > w) std::swap(h, w);
            memset(dp, 0, sizeof(dp));
            printf("%llu
    ", calc(h, w));
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    C# 对 TCP 客户端的状态封装
    一个页面从输入url到页面加载完成究竟经历了些什么
    使用mvp+rxjava+retrofit加载数据
    使用mvp+rxjava+retrofit加载数据
    使用mvp+rxjava+retrofit加载数据
    使用mvp+rxjava+retrofit加载数据
    SqlServer性能检测和优化工具使用详细
    SqlServer性能检测和优化工具使用详细
    SqlServer性能检测和优化工具使用详细
    SqlServer性能检测和优化工具使用详细
  • 原文地址:https://www.cnblogs.com/tonix/p/3828969.html
Copyright © 2020-2023  润新知