leader in tree land
可以用求概率的思想來解決這個問題。令以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!乘上概率就是答案。計算的時候用逆元代替上面的分數即可。
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define mem(x,i) memset(x,i,sizeof(x))
#define sfi(a) scanf("%d", &a)
#define sfii(a,b) scanf("%d %d", &a, &b)
#define sfiii(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define sf scanf
#define pf printf
const
double eps = 1e-10;
const
double pai = acos(-1.0);
const
int inf = 0xfffffff;
const
int mod = 1000000007;
typedef
long
long ll;
const
int maxn = 1005;
int n, k;
vector
g[maxn];
int sz[maxn];
ll dp[maxn][maxn], f[maxn], inv[maxn];
void init()
}ll pow_mod(ll a, ll p, ll n)
void makeinv()
}void makef()
}int dfs(int u, int fa)
return sz[u];
}void solve()
}}int main()
solve();
ll ans = dp[n][k] * f[n] % mod;
pf("case #%d: %lld\n", cas, ans);
}return
0;}
歡迎使用CSDN markdow
本markdown編輯器使用stackedit修改而來,用它寫部落格,將會帶來全新的體驗哦 markdown 是一種輕量級標記語言,它允許人們使用易讀易寫的純文字格式編寫文件,然後轉換成格式豐富的html頁面。維基百科 使用簡單的符號標識不同的標題,將某些文字標記為粗體或者斜體,建立乙個鏈結等,詳細...
歡迎毛毛與妞妞使用CSDN markdown編輯器
建立乙個自定義列表 如何建立乙個註腳 注釋也是必不可少的 katex數學公式 新的甘特圖功能,豐富你的文章 uml 圖表 flowchart流程圖 匯出與匯入 你好!這是你第一次使用markdown編輯器所展示的歡迎頁。如果你想學習如何使用markdown編輯器,可以仔細閱讀這篇文章,了解一下mar...
歡迎使用CSDN markdow1n編輯器
本markdown編輯器使用stackedit修改而來,用它寫部落格,將會帶來全新的體驗哦 markdown 是一種輕量級標記語言,它允許人們使用易讀易寫的純文字格式編寫文件,然後轉換成格式豐富的html頁面。維基百科 使用簡單的符號標識不同的標題,將某些文字標記為粗體或者斜體,建立乙個鏈結等,詳細...