ZOJ - 3201 Tree of Tree
2015-05-18 21:33
411 查看
题目大意:给一棵节点带权的树,找到一个有k个节点的子树,求这个子树的最大权值
解题思路:树形 DP + 背包,f(i, j) 表示以i为根节点的有j个节点子树的最大权值,然后对i的每个子节点做分组背包,因为对于i的每个儿子,可以选择分 1,2,3…j-1 个节点给它
解题思路:树形 DP + 背包,f(i, j) 表示以i为根节点的有j个节点子树的最大权值,然后对i的每个子节点做分组背包,因为对于i的每个儿子,可以选择分 1,2,3…j-1 个节点给它
f(i, j) = max{ max{f(i, j-p) + f(v, p) | 1 <= p < j} | v是i的儿子节点} ans = max{ f[i][k] | 0 <= i < n && i子树节点个数>=k }
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; int N, K, ans, DP[105][105], vis[105]; vector <int> A[105]; void init() { ans = 0; memset(DP, 0, sizeof(DP)); memset(vis, 0, sizeof(vis)); for (int i = 0; i <= N; i++) A[i].clear(); for (int i = 0; i < N; i++) scanf("%d", &DP[i][1]); int x, y; for (int i = 0; i < N - 1; i++) { scanf("%d%d", &x, &y); A[x].push_back(y); A[y].push_back(x); } } void DPS(int root) { vis[root] = 1; int num = A[root].size(); for (int i = 0; i < num; i++) { int child = A[root][i]; if (vis[child]) continue; DPS(child); for (int j = K; j > 0; j--) for (int r = 1; r < j; r++) DP[root][j] = max(DP[root][j], DP[root][j - r] + DP[child][r]); } ans = max(ans, DP[root][K]); } int main() { while (scanf("%d%d", &N, &K) != EOF) { init(); DPS(0); printf("%d\n", ans); } return 0; }
相关文章推荐
- ZOJ 3201 Tree of Tree (树形DP)
- ZOJ 3201 Tree of Tree(树形DP)
- Zoj 3201 Tree of Tree
- zoj 3201 Tree of Tree(树形背包dp)
- ZOJ 3201 Tree of Tree(树形DP+背包)
- ZOJ 3201 Tree of Tree(树形背包DP)
- ZOJ 3201 Tree of Tree
- TOJ 2676 ZOJ 3201 Tree of Tree / 树形DP
- ZOJ 3201 Tree of Tree
- ZOJ 3201 Tree of Tree(树形dp + 分组背包)
- ZOJ 3201 Tree of Tree
- ZOJ - 3201 Tree of Tree
- zoj 3201 简单树形dp Tree of Tree
- ZOJ 3201 Tree of Tree
- ZOJ 3201 Tree of Tree 树形DP
- zoj 3170 7 Levels of Binary Search Tree(BST = =)
- ZOJ 3201 Tree
- ZOJ 3170 7 Levels of Binary Search Tree
- ZOJ-3201 Tree of Tree 树形DP
- zoj 3201 Tree of Tree 树形DP