HDU 5378 (概率dp)

原创 2016年05月30日 17:18:42

Leader in Tree Land

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 626    Accepted Submission(s): 283


Problem Description
Tree land has n cities, connected by n1 roads. You can go to any city from any city. In other words, this land is a tree. The city numbered one is the root of this tree.

There are n ministers numbered from 1 to n. You will send them to n cities, one city with one minister. 

Since this is a rooted tree, each city is a root of a subtree and there are n subtrees. The leader of a subtree is the minister with maximal number in this subtree. As you can see, one minister can be the leader of several subtrees. 

One day all the leaders attend a meet, you find that there are exactly k ministers. You want to know how many ways to send n ministers to each city so that there are kministers attend the meet.

Give your answer mod 1000000007.
 

Input
Multiple test cases. In the first line there is an integer T, indicating the number of test cases. For each test case, first line contains two numbers n,k. Next n1 line describe the roads of tree land.

T=10,1n1000,1kn
 

Output
For each test case, output one line. The output format is Case #xansx is the case number,starting from 1.
 

Sample Input
2 3 2 1 2 1 3 10 8 2 1 3 2 4 1 5 3 6 1 7 3 8 7 9 7 10 6
 

Sample Output
Case #1: 4 Case #2: 316512
 


题意:1-n随机分配给每一个节点,子树的值表示为子树中的节点的最大值.问

所有的子树值有k种的方案数.

每一个节点为根的子树中自身为最大值的概率是1/size(i).然后用f[i][j]表示为

前i个节点中有j种最大值的概率,转移方程就很简单了.因为要避免浮点数,概率

用逆元来搞.

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
#define maxn 1111
#define maxm maxn*2
#define mod 1000000007

struct node {
    int v, next;
}edge[maxn];
int head[maxn], n, k, cnt;
long long dp[maxn];
long long rev[maxn];
long long f[maxn][maxn];

void add_edge (int u, int v) {
    edge[cnt].v = v, edge[cnt].next = head[u], head[u] = cnt++;
}

void dfs (int u, int fa) {
    dp[u] = 1;
    for (int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].v;
        if (v == fa)
            continue;
        dfs (v, u);
        dp[u] += dp[v];
    }
}

long long cal (long long num) {
    return (num%mod+mod)%mod;
}

long long solve () {
    for (int i = 1; i <= n; i++) dp[i] = rev[dp[i]]%mod;
    memset (f, 0, sizeof f);
    f[1][1] = dp[1];
    f[1][0] = cal (1-dp[1]);
    for (int i = 2; i <= n; i++) {
        for (int j = 0; j <= k; j++) {
            f[i][j] += f[i-1][j]*cal (1-dp[i])%mod;
            if (j)
                f[i][j] += f[i-1][j-1]*dp[i]%mod;
            f[i][j] %= mod;
        }
    }
    long long ans = 1;
    for (int i = 2; i <= n; i++)
        ans *= i, ans %= mod;
    return (ans*f[n][k] % mod);
}

void init() {  //预处理逆元
    rev[1] = 1;
    for (int i = 2; i <= 1000; i++){
        rev[i] = (long long)(mod - mod/i) * rev[mod % i] % mod;
    }
}

int main () {
    //freopen ("in.txt", "r", stdin);
    init ();
    int t, kase = 0;
    cin >> t;
    while (t--) {
        cin >> n >> k;
        memset (head, -1, sizeof head);
        cnt = 0;
        printf ("Case #%d: ", ++kase);
        for (int i = 1; i < n; i++) {
            int u, v;
            scanf ("%d%d", &u, &v);
            add_edge (u, v);
            add_edge (v, u);
        }
        dfs (1, 0);
        printf ("%lld\n", solve ());
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

【概率DP】hdu 5819

貌似是去年多校的题,很有营养 题目:http://acm.hdu.edu.cn/showproblem.php?pid=5819 题目意思:有n个骑士,他们如果方向相反,则会发生斗争,...
  • QuanQqqqq
  • QuanQqqqq
  • 2017年03月16日 14:37
  • 2281

(概率DP)正向推概率,反向推期望

为什么要正向推概率,反向推期望呢? 首先,我们看看什么是条件概率。 然后,我们再看看什么是贝叶斯公式。...
  • nameofcsdn
  • nameofcsdn
  • 2016年08月01日 09:05
  • 2147

HDU 4336 概率DP求期望(or容斥原理)

题意: 有N(1
  • c3568
  • c3568
  • 2013年08月11日 16:52
  • 1431

HDU 5378 树形dp转化为线性 计数转化为概率

这道题如果无脑dp的话,复杂度应该至少在(n^3)这个级别,而且转移的式子好像十分容易出错?  也许从计数的角度上来说根本列不出来? 因为两棵子树的方案会互相影响!!!        重点①: 首...
  • lchi1997
  • lchi1997
  • 2017年02月13日 14:07
  • 97

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

题目: http://acm.hdu.edu.cn/showproblem.php?pid=5378 题意: 给你一棵树,有n个人,标号分别是1~n,每个节点放一个人。对于一棵子树来说,标号...
  • u013534690
  • u013534690
  • 2015年08月13日 21:36
  • 327

树形DP,计数DP,概率DP(HDU 5378,Leader in Tree Land)

参考博客 http://blog.csdn.net/firenet1/article/details/47445921 http://blog.csdn.net/pibaixinghei/arti...
  • xl2015190026
  • xl2015190026
  • 2017年07月14日 16:36
  • 125

hdu 5378 Leader in Tree Land 2015多校联合训练赛 树形dp

Leader in Tree Land Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe...
  • firenet1
  • firenet1
  • 2015年08月12日 16:14
  • 755

hdu 5378 Leader in Tree Land dp+逆元

题意: 一棵有n个节点的树中,明显有n棵子树。现在有1~n个数字,让你填充到节点。一棵子树的leader就是这棵子树里面最大的数字,很明显,一个数字可以作为多棵子树的leader。 现在让你找出这...
  • u011580493
  • u011580493
  • 2015年08月13日 10:34
  • 270

【DP】 HDOJ 5378 Leader in Tree Land

状态转移很好想。。。。但是复杂度并不好证明。。。但是确实是n^2的算法。。。 #include using namespace std; typedef long long LL; const ...
  • blankcqk
  • blankcqk
  • 2015年08月12日 10:35
  • 254

HDU 5378 Leader in Tree Land(树形背包+组合数学)

题意:把1到n划分到n个结点的树中,子树的领导是这个子树中权值最大的点。求n个结点的树中,领导为k个的情况数。 思路:树形背包。用dp[i][j]表示以i为根的子树中领导为j个的情况数。 首先用siz...
  • u014664226
  • u014664226
  • 2015年11月15日 17:42
  • 293
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 5378 (概率dp)
举报原因:
原因补充:

(最多只允许输入30个字)