2015多校第7场 HDU 5378 Leader in Tree Land 概率DP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5378

题意:一棵n个节点的树。对其节点进行标号(1~n)。求恰好存在k个节点的标号是其节点所在子树的最大值的方案数。

解法:

首先,总共有n!中标号方案。而如果求出n个节点中出现k个上述节点的概率p。方案数等于n!* p。
dp[i][j] 表示钱i个节点有j个上述节点的概率。转移较容易推出。
dp[i][j] = dp[i-1][j] * (c[i]-1) / c[i] + dp[i-1][j-1] * (1 / c[i]);    c[i] 第i个节点的子树的节点数。

有除法要处理逆元。

//HDU 5378

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9+7;
const int maxn = 1010;
int n, k, edgecnt, head[maxn];
struct edge{
    int to,next;
}E[maxn*2];
void init(){
    edgecnt=0;
    memset(head,-1,sizeof(head));
}
void add(int u, int v){
    E[edgecnt].to=v,E[edgecnt].next=head[u],head[u]=edgecnt++;
}
int sz[maxn];
LL inv[maxn], dp[maxn][maxn];
//dp[i][j]代表前i个点,恰好有j个点是leader的概率
//dp[i][j] = dp[i-1][j]*(sz[i]-1)/sz[i]+dp[i-1][j-1]/sz[i]
void dfs(int u, int pre){
    sz[u] = 1;
    for(int i = head[u]; ~i; i=E[i].next){
        int v = E[i].to;
        if(v == pre) continue;
        dfs(v, u);
        sz[u] += sz[v];
    }
}
void INIT(){
    inv[1] = 1;
    for(int i = 2; i < maxn; i++) inv[i] = 1LL*(mod-mod/i)*inv[mod%i]%mod;
}

int main()
{
    init();
    int T, ks = 0;
    INIT();
    scanf("%d", &T);
    while(T--)
    {
        init();
        scanf("%d %d", &n,&k);
        for(int i=1; i<n; i++){
            int u, v;
            scanf("%d %d", &u,&v);
            add(u, v);
            add(v, u);
        }
        dfs(1, -1);
        memset(dp, 0, sizeof(dp));
        dp[0][0] = 1;
        dp[1][0] = (sz[1]-1)*inv[sz[1]]%mod;
        dp[1][1] = inv[sz[1]];
        for(int i=2; i<=n; i++){
            dp[i][0] = dp[i-1][0]*(sz[i]-1)%mod*inv[sz[i]]%mod;
            for(int j=1; j<=min(i,k); j++){
                dp[i][j] = ((dp[i-1][j]*(sz[i]-1))%mod*inv[sz[i]]%mod)%mod;
                dp[i][j] = (dp[i][j] + (dp[i-1][j-1]%mod*inv[sz[i]]%mod)%mod)%mod;
            }
        }
        LL ans = dp[n][k];

        for(int i=1; i<=n; i++){
            ans = (ans*i)%mod;
        }
        printf("Case #%d: %lld
", ++ks, ans%mod);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/spfa/p/7305512.html