紫皮,各种,非原创

树状数组在我的理解就是在决策过程中具有层次关系,像是树一样,具有上下级关系或者上级对上级一定程度的限制条件

uva 12186

工人的请愿书

下属中不小于 T% 的人签字时会签字递给上级,问至少需要多少人签字才能传给老板

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <cstdlib>
  7. #include <map>
  8. #include <queue>
  9. #include <vector>
  10.  
  11. const int MAXN = + ;
  12. const double ESP = 10e-;
  13. const double Pi = atan(1.0) * ;
  14. const int INF = 0xffffff;
  15. const int MOD = ;
  16. typedef long long LL;
  17. using namespace std;
  18. vector<int>sons[MAXN];
  19. int n,T;
  20. int dp(int u){
  21. if(sons[u].empty()){
  22. return ;
  23. }
  24. int k = sons[u].size();
  25. vector<int>d;
  26. for(int i = ;i < k;i++){
  27. d.push_back(dp(sons[u][i]));
  28. }
  29. sort(d.begin(),d.end());
  30. int c = (k*T - ) / + ;
  31. int ans = ;
  32. for(int i = ;i < c;i++){
  33. ans += d[i];
  34. }
  35. return ans;
  36. }
  37. int main(){
  38. //freopen("input.txt","r",stdin);
  39.  
  40. while(~scanf("%d%d",&n,&T)){
  41. if(!n && !T){
  42. break;
  43. }
  44. for(int i = ;i <= n;i++){
  45. sons[i].clear();
  46. }
  47. for(int i = ;i <= n;i++){
  48. int a;
  49. scanf("%d",&a);
  50. sons[a].push_back(i);
  51. }
  52. printf("%d\n",dp());
  53. }
  54. return ;
  55. }

poj 3442 / uva 1220 Party at Hali-Bula

晚会邀请人,但是上下级不能在一起,求最多能邀请多少人,并且方案是否唯一

d(u,1) 邀请了u,所以其下级不能邀请 所以d(u,1) = sum(d(v,0) );

d(u,0) 没有邀请u,所以其下级,可以邀请也可以不邀请 则 d(u,0) = sum{ max( d(v,0),d(v,1) ) };

f(u,0) 为 1表示不唯一,否则唯一

f(u,1) 表示邀请了u,其方案是否唯一,当f(v,0)不唯一时,则f(u,1)必须不唯一

f(u,0) 没邀请 u 的方案是否唯一,如果 d(v,1) == d(v,0) 或者 由其所取的值得f(v)决定

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cmath>
  4. #include <cstring>
  5. #include <algorithm>
  6. #include <cstdlib>
  7. #include <stack>
  8. #include <cctype>
  9. #include <string>
  10. #include <queue>
  11. #include <map>
  12. #include <set>
  13.  
  14. using namespace std;
  15.  
  16. const int INF = 0xffffff;
  17. const double ESP = 10e-;
  18. const double Pi = * atan(1.0);
  19. const int MAXN = + ;
  20. const long long MOD = ;
  21. const int dr[] = {,,-,,-,,-,};
  22. const int dc[] = {,,,-,,-,-,};
  23. typedef long long LL;
  24.  
  25. LL gac(LL a,LL b){
  26. return b?gac(b,a%b):a;
  27. }
  28. int n;
  29. int d[MAXN][];
  30. int child[MAXN];
  31. bool f[MAXN][];
  32. int cnt;
  33. map<string,int>m;
  34. vector<int>G[MAXN];
  35. int getNum(string str){
  36. int a;
  37. if(m.count(str)){
  38. a = m[str];
  39. }
  40. else{
  41. a = cnt;
  42. m[str] = cnt++;
  43. }
  44. return a;
  45. }
  46. void dp(int r){
  47. if(!G[r].size()){ //没有孩子
  48. d[r][] = ;//如果选择r能获得的最大值
  49. d[r][] = ; //如果不选择r获得的最大值
  50. // f[r][1] = 1;
  51. // f[r][0] = 1;
  52. return;
  53. }
  54. d[r][] = ; //如果选择了r则包含r这个员工
  55. bool flag = ;
  56. // f[r][0] = 1;
  57. int len = G[r].size();
  58. for(int l = ;l < len;l++){
  59. dp(G[r][l]);
  60. int i = G[r][l];
  61. if(f[i][]){
  62. f[r][] = ;
  63. }
  64. d[r][] += d[i][];
  65. if(d[i][] > d[i][]){
  66. d[r][] += d[i][];
  67. if(f[i][])
  68. f[r][] = ;
  69. }
  70. else{
  71. d[r][] += d[i][];
  72. if(d[i][] == d[i][] || f[i][])
  73. f[r][] = ;
  74. }
  75. // if(G[r][i]){
  76. // dp(i);
  77. // if(f[i][0]){
  78. // f[r][1] = 1;
  79. // }
  80. // d[r][1] += d[i][0];
  81. // if(d[i][0] > d[i][1]){
  82. // d[r][0] += d[i][0];
  83. // if(f[i][0])
  84. // f[r][0] = 1;
  85. // }
  86. // else{
  87. // d[r][0] += d[i][1];
  88. // if(d[i][1] == d[i][0] || f[i][1])
  89. // f[r][0] = 1;
  90. // }
  91. //// d[r][1] += d[i][0]; //如果选择了r这其下级不能选择
  92. //// if(!f[i][0]){
  93. //// flag = 0;
  94. //// }
  95. //// if(d[i][0] == d[i][1]){
  96. //// f[i][0] = 0;
  97. //// d[r][0] += d[i][0];
  98. //// }
  99. //// else if(d[i][0] > d[i][1]){
  100. //// d[r][0] += d[i][0];
  101. //// if(!f[i][0]){
  102. //// f[r][0] = 0;
  103. //// }
  104. //// }
  105. //// else{
  106. //// d[r][0] += d[i][1];
  107. //// if(!f[i][1]){
  108. //// f[r][0] = 0;
  109. //// }
  110. //// }
  111. //
  112. // }
  113. // }
  114. // if(flag){
  115. // f[r][1] = 1;
  116. }
  117. return;
  118. }
  119. int main(){
  120. #ifndef ONLINE_JUDGE
  121. freopen("inpt.txt","r",stdin);
  122. // freopen("output.txt","w",stdout);
  123. #endif
  124. while(~scanf("%d",&n) && n){
  125. cnt = ;
  126. memset(child,,sizeof(child));
  127. memset(f,,sizeof(f));
  128. memset(d,,sizeof(d));
  129. string str1;
  130. string str2;
  131. m.clear();
  132. cin >> str1;
  133. m[str1] = cnt++;
  134. int a,b;
  135. for(int i = ;i <= n;i++){
  136. G[i].clear();
  137. }
  138. for(int i = ;i < n;i++){
  139. cin >> str1 >> str2;
  140. a = getNum(str1);
  141. b = getNum(str2);
  142. G[b].push_back(a);
  143. }
  144. dp();
  145. if(d[][] == d[][]){
  146. printf("%d No\n",d[][]);
  147. }
  148. else if(d[][] > d[][]){
  149. printf("%d %s\n",d[][],!f[][]?"Yes":"No");
  150. }
  151. else{
  152. printf("%d %s\n",d[][],!f[][]?"Yes":"No");
  153. }
  154. }
  155. return ;
  156. }

poj 3398 Perfect Service / uva 1218

联通的计算机,从中间抽取几台电脑充当服务器,使每台电脑恰好有一台服务器相连,求最小的服务器数目

d(u,0) u是服务器,其子节点既可以是服务器,也可以不是服务器

d(u,1) u 不是服务器,但是其父亲是服务器,其儿子一定不是服务器

d(u,2) u不是服务器,其父亲也不是服务器,u恰好一个v是服务器

d(u,0) = sum{min(d(v,0),d(v,1)) } + 1;

d(u,1) = sum{d(v,2)};

d(u,2) = sum{d(vv,2)} = min(d(u,1)- d(v,2) + d(v,0)) //其某一个子节点为服务器

因为是无向树所以需要vis标记

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <cstdlib>
  6. #include <cctype>
  7. #include <algorithm>
  8. #include <vector>
  9.  
  10. const int MAXN = + ;
  11. const int INF = 0xffffff;
  12. const int mod = ;
  13. const double Pi = atan(1.0)*;
  14. const double ESP = 10e-;
  15.  
  16. using namespace std;
  17. vector<int>G[MAXN];
  18. int d[MAXN][];
  19. bool vis[MAXN];
  20. int n;
  21. void dp(int u){
  22. vis[u] = ;
  23. int len = G[u].size();
  24. d[u][] = ; //u是服务器,其子节点既可以是服务器,也可以不是,其父节点可以是服务器,也可以不是
  25. d[u][] = ; //u不是服务器,但是u父亲是服务器,所以其子节点都不是服务器
  26. d[u][] = INF; // u,和u的父亲都不是服务器,所以u的子节点必须有点是服务器
  27. vector<int>arr;
  28. for(int i = ;i < len;i++){
  29. int v = G[u][i];
  30. if(vis[v])
  31. continue;
  32. dp(v);
  33. arr.push_back(v);
  34. d[u][] += min(d[v][],d[v][]); // 子节点既可以是服务器又可以不是服务器所以取最小值
  35. d[u][] += d[v][]; // u不是服务器,子节点不是服务器,所以等于d[v][2]父亲和其本身都不是服务器的相加
  36. }
  37. len = arr.size();
  38. for(int i = ;i < len;i++){
  39. int v = arr[i];
  40. d[u][] = min(d[u][],d[u][] - d[v][] + d[v][]);
  41. }
  42. }
  43. int main(){
  44. // freopen("input.txt","r",stdin);
  45. while(~scanf("%d",&n)){
  46. for(int i = ;i <= n;i++){
  47. G[i].clear();
  48. }
  49. memset(vis,,sizeof(vis));
  50. memset(d,,sizeof(d));
  51. for(int i = ;i < n;i++){
  52. int a,b;
  53. scanf("%d%d",&a,&b);
  54. G[b].push_back(a);
  55. G[a].push_back(b);
  56. }
  57. dp();
  58. int ans = INF;
  59. ans = min(d[][],d[][]);
  60. printf("%d\n",ans);
  61. scanf("%d",&n);
  62. if(n < )
  63. break;
  64. }
  65. return ;
  66. }

树状DP的更多相关文章

  1. 树状DP (poj 2342)

    题目:Anniversary party 题意:给出N各节点的快乐指数,以及父子关系,求最大快乐指数和(没人职员愿意跟直接上司一起玩): 思路:从底向上的树状DP: 第一种情况:第i个员工不参与,F[ ...

  2. poj3659树状DP

    Cell Phone Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6273   Accepted: 225 ...

  3. hdu 1561 The more, The Better_树状dp

    题目链接 题意:给你一棵树,各个节点都有价值(除根节点),从根节点出发,选择m个节点,问最多的价值是多小. 思路:很明显是树状dp,遍历树时背包最优价值,dp[i][k]=max{dp[i][r]+d ...

  4. poj 2342 Anniversary party_经典树状dp

    题意:Ural大学有n个职员,1~N编号,他们有从属关系,就是说他们关系就像一棵树,父节点就是子节点的直接上司,每个职员有一个快乐指数,现在要开会,职员和职员的直接上司不能同时开会,问怎才能使开会的快 ...

  5. 树状DP HDU1520 Anniversary party

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题意:职员之间有上下级关系,每个职员有自己的happy值,越高在派对上就越能炒热气氛.但是必须是 ...

  6. [Codeforces743D][luogu CF743D]Chloe and pleasant prizes[树状DP入门][毒瘤数据]

    这个题的数据真的很毒瘤,身为一个交了8遍的蒟蒻的呐喊(嘤嘤嘤) 个人认为作为一个树状DP的入门题十分合适,同时建议做完这个题之后再去做一下这个题 选课 同时在这里挂一个选取节点型树形DP的状态转移方程 ...

  7. HDU 4714 Tree2cycle(树状DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup)

    Description A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 ...

  8. poj2486--Apple Tree(树状dp)

    Apple Tree Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7789   Accepted: 2606 Descri ...

  9. 洛谷P2015 二叉苹果树(树状dp)

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...

  10. 洛谷P1122 最大子树和 (树状dp)

    题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明 ...

随机推荐

  1. 关于FTP操作的功能类

    自己在用的FTP类,实现了检查FTP链接以及返回FTP没有反应的情况. public delegate void ShowError(string content, string title); // ...

  2. C#_会员管理系统:开发五(用户注册)

    创建一个新的用户注册窗体(VIPRegistration.cs): 用户注册窗体(VIPRegistration.cs)详细代码如下: using System; using System.Colle ...

  3. BZOJ 3236: [Ahoi2013]作业( 莫队 + BIT )

    莫队..用两个树状数组计算.时间复杂度应该是O(N1.5logN). 估计我是写残了...跑得很慢... ----------------------------------------------- ...

  4. HDU 3925 Substring 【大数相减】

    题目意思是,给你提供两个数字 a 和 b a 可以不断的往上加, 直到b 为其子串 问的是 a 最小加几? 显而易见,a  的数据范围给了10 ^100非常大,直接模拟肯定不行 那么就用 b 减去 a ...

  5. IE6/7/8 CSS兼容性问题和解决方法汇总

    断断续续的在开发过程中收集了好多的bug以及其解决的办法,都在这个文章里面记录下来了!希望以后解决类似问题的时候能够快速解决,也希望大家能在留言里面跟进自己发现的ie6 7 8bug和解决办法! 1: ...

  6. 使用MongoDB的开源项目(转)

    根据谷歌的搜索结果筛选出来的. 统计应用 counlty https://count.ly/ mongopress 开源CMS系统 http://www.mongopress.org/ Rubedo ...

  7. BZOJ 2429: [HAOI2006]聪明的猴子( MST )

    水题, 求MST即可. -------------------------------------------------------------------------------- #includ ...

  8. javascript每日一练(十三)——运动实例

    一.图片放大缩小 <!doctype html> <html> <head> <meta charset="utf-8"> < ...

  9. C-整数划分

    将正整数 n 表示成一系列正整数之和, n=n1+n2+…+nk, 其中 n1>=n2>=…>=nk>=1 , k>=1 . 正整数 n 的这种表示称为正整数 n 的划分 ...

  10. Git 将本次修改追加在上一次修改上面

    Git 将本次修改追加在上一次修改上面 git add . git commit --amend 之后就是进入日志提交页面 确保change-Id那条记录出现在最后一行,如: zh-->en 修 ...