CSU 1351 Tree Counting

  原题链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1351

  DP题,毫无疑问。由于动态规划题目做得少、不熟悉,刚开始自己用f[i]表示用 i 个节点的方案数,然后就需要逐个子节点进行深搜,非常暴力,毫无疑问TLE。在此情况下,直觉告诉我需要增加一维空间来降低时间复杂度。此时,设dp[i][j]表示用 i 个节点,孩子节点数恰好为 j 的方案数,那么,状态转移方程为:

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

#define N 205
#define M 25
#define MOD 1000000007 

typedef long long LL;

LL dp[N][M];

int main()
{
    int t, n, k;
    cin >> t;
    while(t--)
    {
        cin >> n >> k;
        memset(dp, 0, sizeof dp);
        dp[1][1] = 1; dp[1][0] = 1;
        for(int i = 2; i <= n; i++)
        {
            dp[i][1] = dp[i-1][0];
            for(int j = 2; j <= k; j++)
            {
                if(j >= i) break;
                for(int p = 1; p < i-1; p++)
                {
                    dp[i][j] = (dp[i][j] + dp[i-p][j-1] * dp[p][0]) % MOD;
                }
            }
            for(int j = 1; j <= k; j++)
                dp[i][0] = (dp[i][0] + dp[i][j]) % MOD;
        }
        cout << dp[n][0] << endl;
    }
    return 0;
}
View Code

 

 

 

posted @ 2014-04-17 15:54  芒果布丁  阅读(139)  评论(0编辑  收藏  举报