a tree of n nodes. The node is labeled (1~n). The number of nodes whose nodes are the largest of the subtree in which they exist.
First, a total of n! Medium label Scheme. And if we find out the probability p of K nodes in N nodes. Number of scenarios equals n! * p.
DP[I][J] indicates the probability that the money I node has j nodes above. Transfer is easier to roll out.
DP[I][J] = dp[i-1][j] * (c[i]-1)/c[i] + dp[i-1][j-1] * (1/c[i]); C[i] The number of nodes of the subtree of the first node.
Then, double must not be able to live. So foolishly used the structure to save a score. Then the denominator was multiplied to explode long long. And then, with the GT, Meow three debug an afternoon =. = Strange I do not understand the inverse, the pit of two bits.
Inverse: http://cn.bing.com/is roughly the same as the number of modulo equals to the inverse of the numbers to take the mold bar ...
So the transfer became:
DP[I][J] = dp[i-1][j] * (c[i]-1) * INV (C[i]) + dp[i-1][j-1] * INV (C[i])
The DP is then transferred within the integer.
/*********************************************** * * Problem ID:hdu_5378.cpp * * Create time:wed 12 11:14:30 2 015 * * Auther name:xuelanghu * * Auther blog:blog.csdn.net/xuelanghu407 ***************************************** /#include <cstdio> #include <vector> #include <cstring> #include <iostream> #include < algorithm>using namespace Std;const int maxn = + 5;const long Long MOD = (long Long) (1e9 + 7); struct Node {lo Ng long A, b; Node () {a = 0; b = 1;} Node (Long long _a, Long long _b): A (_a), B (_b) {}};long long _gcd (long long A, long long B) {if (b = = 0) return A; else return _GCD (b, a%b);} Inline node Add (node x, node Y) {Long long rec, RES, TMP; rec = x.a*y.b + x.b*y.a; res = x.b*y.b; TMP = _GCD (REC, res);/if (TMP = = 0) tmp = 1; Return Node (rec/tmp, res/tmp);} Inline node Mul (node x, node Y) {Long long rec, RES, TMP; REC = x.a * Y.A; res = x.b * Y.B; TMP = _GCD (REC, res);//IF (tmp = = 0) tmp = 1; Return Node (rec/tmp, res/tmp);} int N, k;vector<int> v[maxn];long long Dp[maxn][maxn];long long C[maxn];long long dfs (int t, int fa) {lon G Long cnt = 1L; for (int i=0; i<v[t].size (); i++) {if (v[t][i] = = FA) continue; CNT + = DFS (v[t][i], T); } return c[t] = cnt;} Long long A, long long, p) {Long long res=1l; while (p) {if (p&1) res = (res*a)%mod; A = (a*a)%mod; P >>= 1; } return res; A long long, INV (long long a) {return power (A, MOD-2); } Long Long _in[maxn];void init () {for (int i=1; i<=1002; i++) {_in[i] = INV (i); }}long long F (int n) {Long Long res = 1; for (int i=1; i<=n; i++) {res = (res * (Long Long) (i))% MOD; } return res; int main () {int t_case; Init (); scanf ("%d", &t_case); for (int i_case=1; i_case<=t_case; ++i_case) {scanf ("%d%d", &n, &k); for (int i=0; i<=n; i++) v[i].clear (); Memset (c, 0,sizeof (c)); int A, B; for (int i=1; i<n; i++) {scanf ("%d%d", &a, &b); V[a].push_back (b); V[b].push_back (a); } DFS (1,-1); Dp[1][0] = ((c[1]-1) * _in[c[1]])%mod; DP[1][1] = 1 * _in[c[1]]; cout << dp[1][0].a << "/" << dp[1][0].b << ""; cout << dp[1][1].a << "/" << dp[1][1].b << Endl; for (int i=2; i<=n; i++) {//dp[i][0] = Mul (dp[i-1][0], Node (C[i]-1, c[i])); Dp[i][0] = ((dp[i-1][0] * (c[i]-1))% mod * _in[c[i]])% MoD; for (int j=1; J<=min (i, k); j + +) {//DP[I][J] = Add (Mul (Dp[i-1][j], Node (C[i]-1, C[i])), Mul (dp[i-1][j-1), Node (1, c[i])); DP[I][J] = ((((((dp[i-1][j) * (c[i]-1)% MoD) * _in[c[i]])% mod + (dp[i-1][j-1] * _in[c[i])% MoD)% MOD; if (i = = N && j = = k) cout << "hahahaha~" << Endl; cout << dp[i][j].a << "/" << dp[i][j].b << ""; if (dp[i][j].b <= 0) dp[n+100][k+1].b = 100; }//cout << Endl; } Long Long res = dp[n][k]; cout << res.a << "/" << res.b << Endl; Long Long ans = (f (n) * res)% MOD; printf ("Case #%d:%d\n", i_case, (int) ans); } return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU 5378 probability dp Inverse