USACO nocows

不錯的DP題。設dp[i][j]表示 i個點組成的等於k高度的滿足題意的個數,這樣高度要求是k的就直接引用,後面的應該不用說了吧。任何高度爲Hi的樹都是兩個子樹構成,一個必須高度爲Hi-1,另外一個無所謂。

但是要注意重複。注意代碼註釋部分。


/*
ID: fairyroad
TASK:nocows
LANG:C++
*/
#include<fstream>
using namespace std;
ifstream fin("nocows.in");
ofstream fout("nocows.out");

unsigned long dp[201][101];
unsigned long N, K;

inline unsigned long MAX(unsigned long a, unsigned long b){ return a > b ? a : b;}

int main()
{
    fin>>N>>K;
    unsigned long res = 0;
    unsigned long i, j;
    unsigned long p, q;
    dp[1][0] = 1;
    dp[1][1] = 1;
    for(i = 3; i <= N; i+=2) // dynamic programming
    {
        unsigned long upper = i>>1;
        for(j = 1; j <= upper ; j+=2) // enumerating sub-tree, j : number of nodes
        {
            for(p = 1; p <= dp[j][0]; ++p) // traversing various sub-tree's height
            {
                for(q = 1; q <= dp[i-1-j][0]; ++q)
                {
                    if(dp[j][p] && dp[i-1-j][q])
                    {
                        unsigned long height = MAX(p, q)+1;
                        if(height > dp[i][0])
                            dp[i][0] = height;
                        res = (dp[j][p]*dp[i-1-j][q])<<1; // 直接翻轉
                        if(i-1-j == j) // 防止重複
                            res>>=1;
                        dp[i][height] = (dp[i][height]+res)%9901;
                    }
                }
            }
        }
    }
    fout<<dp[N][K]%9901<<endl;
    return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章