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;
}




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