HDU 5378 Leader in Tree Land 树形背包

链接

题解来源:点击打开链接

题意:

给定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;
}
/*
99
5 3
1 2
2 3
2 4
1 5

4 2
1 2
2 3
2 4

ans:12

4 3
1 2
2 3
2 4

4 4
1 2
2 3
2 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  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 # x ans x  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
 

Source
2015 Multi-University Training Contest 7
 

你可能感兴趣的:(HDU 5378 Leader in Tree Land 树形背包)