设为首页 加入收藏

TOP

hdu 5378 Leader in Tree Land(dp+逆元)
2015-11-21 00:54:53 来源: 作者: 【 】 浏览:1
Tags:hdu 5378 Leader Tree Land +逆元

?

?

问题可以理解成N个节点的树,有K个ministers的概率,最后乘上N!。每个节点为ministers的概率即为1 / son(以该节点为根节点的子树包含的节点个数),同样不为ministers的概率为(son-1)/son。所以没有必要考虑树的结构,直接根句子节点的个数转移dp[i][j]

dp[i][j] = dp[i-1][j-1] * 1 / son[u]

dp[i][j] = dp[i-1][j] * (son[u]-1]) / son[u]

取模的部分可以用逆元。

?

?

#include 
  
   
#include 
   
     #include 
    
      #include 
     
       using namespace std; typedef long long ll; const int mod = 1000000007; const int maxn = 1005; int fac[maxn]; int N, K, son[maxn]; ll dp[maxn][maxn]; vector
      
        G[maxn]; void dfs (int u, int f) { son[u] = 1; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (v == f) continue; dfs(v, u); son[u] += son[v]; } } void init () { scanf(%d%d, &N, &K); for (int i = 1; i <= N; i++) G[i].clear(); int u, v; for (int i = 1; i < N; i++) { scanf(%d%d, &u, &v); G[u].push_back(v); G[v].push_back(u); } dfs(1, 0); } void exgcd (ll a, ll b, ll& d, ll& x, ll&y) { if (!b) d = a, x = 1, y = 0; else { exgcd(b, a%b, d, y, x); y -= x * (a/b); } } ll inv (ll a) { ll d, x, y; exgcd(a, mod, d, x, y); return d == 1 ? (x + mod) % mod : -1; } int solve () { memset(dp, 0, sizeof(dp)); dp[0][0] = 1; for (int i = 1; i <= N; i++) { for (int j = 0; j <= K; j++) { if (dp[i-1][j] == 0) continue; dp[i][j] = (dp[i][j] + dp[i-1][j] * (son[i] - 1) % mod * inv(son[i])) % mod; dp[i][j+1] = (dp[i][j+1] + dp[i-1][j] * inv(son[i])) % mod; } } return dp[N][K] * fac[N] % mod; } int main () { fac[1] = 1; for (int i = 2; i <= 1000; i++) fac[i] = 1LL * i * fac[i-1] % mod; int cas; scanf(%d, &cas); for (int kcas = 1; kcas <= cas; kcas++) { init (); printf(Case #%d: %d , kcas, solve()); } return 0; } 
      
     
    
   
  


?

?

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDU 3397 Sequence operation(区.. 下一篇hdu 5379 Mahjong tree(树形dp)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: