**HDU 5378 - Leader in Tree Land(概率DP)

来源:互联网 发布:淘宝高仿手表店铺 编辑:程序博客网 时间:2024/04/27 21:28

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=5378

题意:

给你一棵树,有n个人,标号分别是1~n,每个节点放一个人。对于一棵子树来说,标号最大的那个人为领导,求出领导为k个的方案数。

思路:

直接复制题解思路,奇妙的想法!

可以用求概率的思想来解决这个问题。令以i号节点为根的子树为第i棵子树,设这颗子树恰好有sz[i]个点。那么第i个点是第i棵子树最大值的概率为1/sz[i],不是最大值的概率为(sz[i]-1)/sz[i]。现在可以求解恰好有k个最大值的概率。

令dp[i][j]表示考虑编号从1到i的点,其中恰好有j个点是其子树最大值的概率。 很容易得到如下转移方程:dp[i][j]=dp[i-1][j]*(sz[i]-1)/sz[i]+dp[i-1][j-1]/sz[i]。这样dp[n][k]就是所有点中恰好有k个最大值的概率。

题目要求的是方案数,用总数n!乘上概率就是答案。计算的时候用逆元代替上面的分数即可

AC.

#include <iostream>#include <cstdio>#include <vector>#include <cstring>using namespace std;typedef long long ll;const int mod = 1e9+7;const int maxn = 1005;vector<int> g[maxn];ll fac[maxn], in[maxn];ll dp[maxn][maxn];ll pmod(ll a, ll n){    ll r = 1;    while(n > 0) {        if(n & 1) r = r*a % mod;        a = a*a %mod;        n >>= 1;    }    return r;}int sz[maxn];void dfs(int u, int fa){    sz[u] = 1;    for(int i = 0; i < g[u].size(); ++i) {        int v = g[u][i];        if(v == fa) continue;        dfs(v, u);        sz[u] += sz[v];    }}int main(){    //freopen("in", "r", stdin);    fac[0] = 1;    in[1] = 1;    for(int i = 1; i < maxn; ++i) {        fac[i] = fac[i-1]*i%mod;        in[i] = pmod(i, mod-2); //ÄæÔª    }    int T, ca = 1;    scanf("%d", &T);    while(T--) {        int n, k;        scanf("%d %d", &n, &k);        for(int i = 0; i <= n; ++i) {            g[i].clear();        }        memset(sz, 0, sizeof(sz));        for(int i = 0; i < n-1; ++i) {            int u, v;            scanf("%d %d", &u, &v);            g[u].push_back(v);            g[v].push_back(u);        }        dfs(1, 1);        memset(dp, 0, sizeof(dp));        dp[0][0] = 1;        for(int i = 1; i <= n; ++i) {            for(int j = 0; j <=k; ++j) {                dp[i][j] = dp[i-1][j] * (sz[i] - 1) %mod * in[sz[i]] % mod                        + dp[i-1][j-1] * in[sz[i]] % mod;                dp[i][j] %= mod;            }        }        ll ans = dp[n][k] * fac[n] % mod;        printf("Case #%d: %I64d\n", ca++, ans);    }    return 0;}


0 0
原创粉丝点击