【題意】:給定一棵樹(shù),給定邊權(quán)的區(qū)間[0,L],求最終樹(shù)的最長(zhǎng)路<=S的概率; 

【題解】:武大校賽的樹(shù)dp,放了好久,看著題解勉強(qiáng)過(guò)了。只可以說(shuō)我的樹(shù)dp太水了,還停留在背包的階段。
              設(shè)狀態(tài)dp[i][j]表示以i為根的子樹(shù),其葉子結(jié)點(diǎn)到i的最長(zhǎng)距離為j且該子樹(shù)最長(zhǎng)路徑不超過(guò)s的概率。
              對(duì)于u的一個(gè)子樹(shù)v,先枚舉u連v的長(zhǎng)度,然后再把之前的子樹(shù)和v這條鏈合并,好復(fù)雜,不會(huì)表達(dá)了,直接研究代碼吧。

【代碼】:
 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "vector"
 6 #include "queue"
 7 #include "cmath"
 8 #include "string"
 9 #include "cctype"
10 #include "map"
11 #include "iomanip"
12 using namespace std;
13 #define pb push_back
14 #define mp make_pair
15 #define fi first
16 #define se second
17 #define lc(x) (x << 1)
18 #define rc(x) (x << 1 | 1)
19 #define lowbit(x) (x & (-x))
20 #define ll long long
21 #define maxn 70
22 #define maxs 530
23 int n, l, s;
24 double dp[maxn][maxs];
25 double son[maxs], tmp[maxs];
26 double e;
27 vector<int> vec[maxn];
28 void dfs(int u, int fa) {
29     memset(dp[u], 0, sizeof(dp[u]));
30     dp[u][0] = 1.0;
31     int size = vec[u].size();
32     for(int i = 0; i < size; i++) {
33         int v = vec[u][i];
34         if(v == fa) continue;
35         dfs(v, u);
36         memset(son, 0, sizeof(son));
37         memset(tmp, 0, sizeof(tmp));
38         for(int j = 0; j <= l; j++)
39             for(int k = 0; k <= s; k++)
40                 if(j + k <= s)
41                     son[j+k] += e * dp[v][k];
42         for(int j = 0; j <= s; j++)
43             for(int k = 0; k <= s - j; k++)
44                 tmp[max(j, k)] += son[j] * dp[u][k];
45         for(int j = 0; j <= s; j++)
46             dp[u][j] = tmp[j];
47     }
48 }
49 
50 int main() {
51     int T, Case = 1;
52     scanf("%d", &T);
53     while(T--) {
54         scanf("%d%d%d", &n, &l, &s);
55         for(int i = 0; i <= n; i++) vec[i].clear();
56         e = 1.0 / (1.0 + l);
57         for(int i = 1; i < n; i++) {
58             int a, b;
59             scanf("%d%d", &a, &b);
60             vec[a].pb(b);
61             vec[b].pb(a);
62         }
63         dfs(1, -1);
64         double ans = 0.0;
65         for(int i = 0; i <= s; i++) ans += dp[1][i];
66         printf("Case %d: %.6f\n", Case++, ans);
67     }
68     return 0;
69 }
70