UVa 12186 Another Crisis(树形DP)
2015-02-07 21:34
411 查看
题目链接:http://arena.acmclub.com/problem.php?id=16295
题意:
给出一个树状关系图,公司里只有一个老板编号为0,其他人员从1开始编号。除了老板,每个人都有一个直接上司,没有下属的员工成为工人。工人们想写一份加工资的请愿书,只有当不少于员工的所有下属的T%人递交请愿书后,该员工才会将请愿书递交给他的直接上级。输出能递交到老板处,最少需要多少工人写请愿书。
分析:
d(u)表示让u给上级发信最少需要多少个工人。假设u有k个子节点,则至少需要c = (k*T - 1) / 100 + 1 个直接下级发信给他才行。把所有子节点的d从小到大排序,前c个和就是d(u)。
如何理解这一步?设 x = 结点的人数*百分比。根结点个子结点,前c个x值最小的结点的和,就是最后的结果。根结点的子结点,同样需要满足,前c个x值最小的结点的和,才能签字。同理,根结点的孙结点、子孙结点……一直到最后一层,最后一层称为叶结点,即没有子结点,当程序访问到这一层的时候,直接返回1,即叶结点本身。
用深度优先的方式,求出根结点的每个子结点的d值,将前c个最小的d值相加,就能得出结果。建议画图辅助理解,详见代码与注释。
所求答案就是d(0)。
这里考虑到浮点误差,所以才将 k*T / 100 写为 (k*T - 1) / 100 + 1 , 这样一来c就是 不少于k的T%的最小整数。
输入:
第一行输入n(员工数)、 t(百分比)。
第二行输入编号从1到n的员工的直接上司。
输出:
输出最少需要的人数。
本菜鸡的一点思考,如有不正确的地方,欢迎指教。
题意:
给出一个树状关系图,公司里只有一个老板编号为0,其他人员从1开始编号。除了老板,每个人都有一个直接上司,没有下属的员工成为工人。工人们想写一份加工资的请愿书,只有当不少于员工的所有下属的T%人递交请愿书后,该员工才会将请愿书递交给他的直接上级。输出能递交到老板处,最少需要多少工人写请愿书。
分析:
d(u)表示让u给上级发信最少需要多少个工人。假设u有k个子节点,则至少需要c = (k*T - 1) / 100 + 1 个直接下级发信给他才行。把所有子节点的d从小到大排序,前c个和就是d(u)。
如何理解这一步?设 x = 结点的人数*百分比。根结点个子结点,前c个x值最小的结点的和,就是最后的结果。根结点的子结点,同样需要满足,前c个x值最小的结点的和,才能签字。同理,根结点的孙结点、子孙结点……一直到最后一层,最后一层称为叶结点,即没有子结点,当程序访问到这一层的时候,直接返回1,即叶结点本身。
用深度优先的方式,求出根结点的每个子结点的d值,将前c个最小的d值相加,就能得出结果。建议画图辅助理解,详见代码与注释。
所求答案就是d(0)。
这里考虑到浮点误差,所以才将 k*T / 100 写为 (k*T - 1) / 100 + 1 , 这样一来c就是 不少于k的T%的最小整数。
输入:
第一行输入n(员工数)、 t(百分比)。
第二行输入编号从1到n的员工的直接上司。
输出:
输出最少需要的人数。
本菜鸡的一点思考,如有不正确的地方,欢迎指教。
import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; public class Main16295 { static int max = 100000 + 10; static ArrayList[] sons = new ArrayList[max]; static int n, t; public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNextInt()) { n = in.nextInt(); t = in.nextInt(); if (n == 0 && t == 0) break; for (int i = 0; i <= n; i++) { sons[i] = new ArrayList(); } for (int i = 1; i <= n; i++) { int x = in.nextInt();//每个上司。 sons[x].add(i);//添加每个上司的直系下属。 } System.out.println(dp(0)); } } public static int dp(int u) { if (sons[u].isEmpty())//访问到叶结点时,返回它本身,即1。 return 1; int k = sons[u].size(); ArrayList d = new ArrayList();//d(u)表示让u给上级发信最少需要多少个工人。 for (int i = 0; i < k; i++) { d.add(dp((int) sons[u].get(i)));//这里用深度优先进行添加。 } Object[] a = d.toArray();//由于ArrayList没有直接排序功能 Arrays.sort(a);//故先转为Object[],再排序。 int c = (k * t - 1) / 100 + 1; int ans = 0; for (int i = 0; i < c; ++i) { ans += (int) a[i];//前c个最小的d值就是所求。 } return ans; } }
相关文章推荐
- UVA12186--- Another Crisis (树形dp)
- 树形dp uva 12186 Another Crisis
- uva 12186 Another Crisis 树形dp
- UVA 12186 Another Crisis [树形dp]
- UVA 12186 - Another Crisis(树形DP)
- UVa - 12186 - Another Crisis ( 树形DP )
- UVA-12186 Another Crisis 树形dp
- Another Crisis - UVa 12186 树形dp
- UVA 12186 Another Crisis(树形DP)
- UVA 12186 Another Crisis(树形DP)
- UVA 12186 Another Crisis 树形DP
- UVA - 12186 Another Crisis (树形dp)
- UVa 12186 - Another Crisis(树形DP)
- UVA - 12186 Another Crisis (树形DP)
- UVa 12186 - Another Crisis(树形DP)
- UVA - 12186 Another Crisis (树形dp)
- 【树形DP】UVa 12186 Another Crisis
- uva 12186 lrj-P282 简单树形dp
- UVa 12186 工人的请愿书(树形DP)
- UVa 12186 树形dp