HDU 5378 Leader in Tree Land 树形背包

来源:互联网 发布:全新英朗刷启停软件 编辑:程序博客网 时间:2024/05/11 10:54

链接

题解来源:点击打开链接

题意:

给定n k

下面n-1行给出一棵树。

把数字1-n填到树的节点上。

填完后计算leader节点个数,若这个点是leader,则这个点上填的数>这个点的子树上填的数

问:恰好有k个leader节点的 填涂方案数.


思路:

dp[i][j]表示以i点为根的子树 有恰好j个leader的方案数。

如果u 是叶子节点则 dp[u][0] = 0, dp[u][1] = 1;

如果u不是叶子节点:

先不考虑u点能否成为leader,背包一下。

然后考虑u点:若u能成为leader,设siz[u]表示u的子树节点个数。

那么对于u的子树来说,要把[1, siz[u] ]填到子树上,当u是leader, u只能填 siz[u]

而子树的分配方案就是一个多重集的排列,因为分配给子树的是组合,子树之间是排列。

设u成为leader的方法数为 x1

x1 = (siz[u]-1)! / siz[v1]! / siz[v2]! ····

那么dp[u][i] = dp[u][i] * (u的子树填涂的总方案数 - x1) + dp[u][i-1] * x1


#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstdio>#include <algorithm>#include <string>#include <cmath>#include <cstring>#include <queue>#include <set>#include <map>#include <vector>using namespace std;template <class T>inline bool rd(T &ret) {char c; int sgn;if (c = getchar(), c == EOF) return 0;while (c != '-' && (c<'0' || c>'9')) c = getchar();sgn = (c == '-') ? -1 : 1;ret = (c == '-') ? 0 : (c - '0');while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');ret *= sgn;return 1;}template <class T>inline void pt(T x) {if (x < 0) {putchar('-');x = -x;}if (x > 9) pt(x / 10);putchar(x % 10 + '0');}typedef pair<int, int> pii;typedef long long ll;const int N = 1005;const int mod = 1e9 + 7;const int inf = 1e9;int Pow(int x, int y) {int ans = 1;while (y) {if (y & 1)ans = (ll)ans*x%mod;y >>= 1;x = (ll)x*x%mod;}return ans;}vector<int>G[N];int n, k;int dp[N][N], siz[N], lef[N];int A[N];int mul(int x, int y) {x = (ll)x*y%mod;return x;}inline void add(int &x, int y) {x += y; if (x >= mod)x -= mod;}inline void sub(int &x, int y) {x -= y; if (x < 0)x += mod;}inline void dv(int &x, int y) {x = (ll)x*Pow(y, mod - 2) % mod;}int g[N];void dfs(int u, int fa) {siz[u] = 1; lef[u] = 0;for (auto v : G[u]) {if (v == fa)continue;dfs(v, u);siz[u] += siz[v];}if (siz[u] == 1) {dp[u][0] = 0; dp[u][1] = 1;lef[u] = 1;return;}dp[u][0] = 1;int x1 = A[siz[u] - 1], x2 = A[siz[u]];siz[u] = 0;for (auto v : G[u]) {if (v == fa)continue;for (int i = lef[u] + lef[v]; i <= min(k, siz[u] + siz[v]); i++)g[i] = 0;for (int i = lef[u]; i <= min(k, siz[u]); i++){for (int j = lef[v]; j <= min(k, siz[v]) && i + j <= k; j++){add(g[i + j], mul(dp[v][j], dp[u][i]));}}for (int i = lef[u] + lef[v]; i <= min(k, siz[u] + siz[v]); i++)dp[u][i] = g[i];siz[u] += siz[v];lef[u] += lef[v];dv(x1, A[siz[v]]);dv(x2, A[siz[v]]);}siz[u]++;sub(x2, x1);for (int i = min(siz[u], k); i >= lef[u]; i--) {int tmp = 0;add(tmp, mul(dp[u][i], x2));if (i - 1 >= lef[u])add(tmp, mul(dp[u][i - 1], x1));dp[u][i] = tmp;}}int main() {A[0] = 1;for (int i = 1; i < N; i++)A[i] = (ll)A[i - 1] * i%mod;int T, Cas = 1; rd(T);while (T--) {rd(n); rd(k);for (int i = 1; i <= n; i++)G[i].clear(), memset(dp[i], 0, sizeof dp[i]);for (int i = 1, u, v; i < n; i++) {rd(u); rd(v);G[u].push_back(v); G[v].push_back(u);}dfs(1, 1);printf("Case #%d: ", Cas++);pt(dp[1][k]); puts("");}return 0;}/*995 31 22 32 41 54 21 22 32 4ans:124 31 22 32 44 41 22 32 4*/






















Leader in Tree Land

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


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 k ministers 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 n1line 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
23 21 21 310 82 13 24 15 36 17 38 79 710 6
 

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

Source
2015 Multi-University Training Contest 7
 

0 0