树形DP之个人整理总结
OI题目类型总结整理
OI题⽬类型总结整理本蒟蒻的⼩整理qwq~~持续更新(咕咕咕)数据结构数据结构——线段树推荐yyb dalao的总结——以后维护线段树还是把l,r写到struct⾥⾯吧,也别写len了,调试不好调qwq初始化和叶节点初始化不太⼀样qwq,有的需要统⼀初始化的就⼀定注意不要写到if(l==r)⾥⾯qwq求区间最⼤⼦段和例题:codevs动态最⼤⼦段和维护区间和,区间前缀最⼤⼦段和,区间后缀最⼤⼦段和,区间最⼤⼦段和。
然后合并。
(注意这种跨左右⼦树还有可能会有贡献的线段树写法上和普通的线段树不同!)、求区间最⼤连续⼦段(⽐如说求⼀个区间内最长0⼦段的个数)例题:SHOI脑洞治疗仪维护区间前缀最⼤,后缀最⼤。
然后合并即可。
需要注意的⼀点是下⾯代码⾥⾯的取min(也就是带询问的区间更改⼀定要注意!前后缀长度是不能超过这个长度的):if(rr<=mid) return query(ls(x),ll,rr);else if(mid<ll) return query(rs(x),ll,rr);else{int cur1=query(ls(x),ll,mid);int cur2=query(rs(x),mid+1,rr);int z1=min(t[ls(x)].maxr,mid-le[x]+1);int z2=min(t[rs(x)].maxl,ri[x]-mid);return max(max(cur1,cur2),z1+z2);}线段树模拟⽹络流例题:codeforces280div.1D这是个神仙啊!!!主要⽬的是为了优化时间复杂度,就是考虑最⼤费⽤流怎么跑的,我们⽤区间反转模拟退流过程即可。
具体实现请看博⽂题解。
时间复杂度O(klogn)⼀条链,两点之间有给出的距离,要求logn的时间复杂度内,求出⼀段区间中∑任意两点之间的距离和。
例题:HAOI⾼速公路ans=∑r i=l a[i]∗(i−l+1)∗(r−i+1)ans=∑r i=l a[i]∗(−i2+(r+l)i+(r−l+1−rl))线段树维护即可求历史最值(线段树模板3)例题:CPU监控将操作转换成(a,b),表⽰最终结果为min(x+a,b)。
树型动态规划 tree dp
树型动态规划的应用(讲稿)树型dp是近年来才出现并迅速流行的一种新体型,到目前已经在各种oi竞赛中广泛出现,今天我们就对它做一点基本的探讨。
首先我们结合一个例子来说明什么是树型dp以及它的一些特点。
我们先来简述一下题意,题目给出了一棵圣诞树,树上的每个结点都有一盏灯,一盏灯可以打开当且仅当它的所有孩子结点上的灯是开的,最终要将根结点上的灯打开,每一种不同的开灯方案都对应着一个在任意时刻同时亮着的灯的数目的最大值,要求一种开灯方案,使得这个最大值最小。
问题描述这是安徽省1999年省赛的题目,虽然比较古老,但是很有典型性。
如图,根结点是C,他有3个孩子,为了要打开1,我们要打开D、B、E,从直观上考虑,,我们如果计划先打开B,那么一定不会在还没有打开B之前就去进行一些对打开B没有帮助的工作,比如试图打开D,这不难证明,我们完全调整一下策略,先打开了B,再去打开D,这样至少不必原来的方案差,那么我们再来考虑如何打开B,这是我们需要处理的是以B为root的一棵树,而目标也是一样的,使得在任意时刻同时亮着的灯的数目的最大值最小,我们发现这个问题与原问题是十分类似的,实际上这就是本问题的最优子结构,它完全符合动态规划的性质,也可以dp求解,比如我们求出打开打开一个结点root的所有孩子son[1],son[2],son[3]…son[k]分别需要dp[1],dp[2],dp[3],…,dp[k],且dp数组已经按照从大到小排序,那么我们就应该按照这个顺序来开灯,既先开第一个孩子,…….,本问题得以解决。
以上的问题还可以做出一些拓展,OIBH#8练习赛的攻占巴格达一题就是由本题引申而来的,后面我们会详细讨论。
上面是例子不难,我们来归纳一下树型dp这种dp模型的一般特点。
1 题目往往是一个树的模型2 题目往往是要求一个最优化问题3 题目的问题具有最优子结构,可以递归求解4 树的优美性可以保证dp的无后效性下面我们由易到难看几个例子:Baltic Gems题目描述题目的意思十分简单,给出一棵树,要求你为树上的结点标上权值,权值可以是任意的正整数,唯一的限制条件是相临的两个结点不能标上相同的权值,要求一种方案,使得整棵树的总价值最小。
数模经验总结
下面总结一些小小的经验:1、组队很重要,队友们一定要能谈得来(曾经发生一组队员互相不服气,结果各自做各的,成绩就可想而知了),除此之外,队员之间一定要各有所常,建模嘛,无非就是查阅文献,建立模型,分析数据,编程,写文章,较对等等,保证你们组每个人都会有一些强项,当然男女生也应该都是要有的,所谓男女搭配,干活不累,嘿嘿;2、文章整洁很重要。
如果你是评委的话,肯定喜欢写的文章有条理,图文并茂之类的文章,将心比心,抓住评委的心才是最重要。
3、做建模创新很重要。
这么多的文章你的要想脱颖而出,创新也必须的,当然,你可以想你这篇文章结合了什么什么方法,最好把那方法说得天花乱坠,但不可华而不实,这就行啦。
4、摘要很重要。
以前大学生比赛的时候,是先通过摘要就刷一批,我觉得这是很公平的方法,摘要就是说明你这篇文章的特色和结构的,如果摘要我都不愿意看,干嘛花时间看你的正文。
5、人品很重要,还是我那句话,莫要太看重结果,抱着神马都是浮云的心态~~~数模经历入门篇平时有不少人会加我QQ,然后问诸如“什么是数模”“我该怎么学数模”之类的问题。
这里不是不鼓励大家和我讨论,而是有些问题google或baidu一下很容易得到答案,完全没有必要去问学长或老师。
而且使用搜索引擎的能力在数学建模中也是一个非常重要的能力。
这里推荐一些书,建议刚接触数学建模的朋友们看姜启源、谢金星的《数学模型》,这本书比较全面地介绍了数学建模中一些基本的、常用的模型和方法,有很多的例子,可以全面地了解什么是数学模型,也能基本地掌握如何抽象建模等。
希望进一步深入的同学推荐姜启源、谢金星的《数学模型案例集》,这本书里有不少比较有意思的问题,可以尝试自己做一下,难度比正式比赛要差很多,但是对于初学者来说比较容易上手。
也推荐叶其孝的那套黑书,虽然内容有点老,但是有很多比较有意思的解题思路等。
这里推荐一个很不错的数学建模网站:,那里有很多非常不错的学习资料。
对于那些已经有一些数学建模基础的同学则不推荐读叶其孝的那套书,而是可以直接在网上找一些往年国一或是美赛特等的文章,仔细阅读,了解其中的方法,然后自己动手重新做一遍。
acm中dp问题简单入门讲解
ACM暑期集训报告院系:专业:年级:学号:姓名:日期:西南交通大学目录目录.................................................. 错误!未定义书签。
第1章动态计划(dp) ............................ 错误!未定义书签。
简介.................................................... 错误!未定义书签。
教师内容................................................ 错误!未定义书签。
大体dp——背包问题..................................... 错误!未定义书签。
假设干经典dp及常见优化.................................. 错误!未定义书签。
类似题目................................................. 错误!未定义书签。
参考文献........................................... 错误!未定义书签。
附录1 暑期集训心得体会............................. 错误!未定义书签。
第1章动态计划(dp)(题目采纳2号黑体居中,下空1行)简介(题目采纳四号黑体,正文内容采纳小四号字体,倍行距)在解决问题的时候咱们常常碰到这种问题:在多种方式的操作下咱们如何取得一个最优的方式让咱们取得中意的结果。
这时咱们大多人的思想确实是贪婪。
不错贪婪确实是一个不错的算法,第一他简单容易想到,咱们在操作起来也比较容易。
此刻我推荐几道咱们oj上的贪婪算法的题:soj1562药品运输 soj1585 Climbing mountain。
为了引入动归算法我先拿药品运输这道题简单说一下贪婪算法。
例如1:药品运输(题目采纳小四号Times New Roman字体)Description大地震后,某灾区急需一批药品,此刻有N种药品需要运往灾区,而咱们的运输能力有限,此刻仅有M辆运输车用来运输这批药品,已知不同的药品对灾区具有不同的作用(“作用”用一个整数表示其大小),不同的药品需要的运输力(必要的车辆运载力)不同,而不同的车辆也具有不同的运输力。
树形dp
树形dpAnniversary partyTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7954 Accepted Submission(s): 3462Problem DescriptionThere is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure of employees. It means that the supervisor relation forms a tree rooted at the rector V. E. Tretyakov. In order to make the party funny for every one, the rector does not want both an employee and his or her immediate supervisor to be present. The personnel office has evaluated conviviality of each employee, so everyone has some number (rating) attached to him or her. Your task is to make a list of guests with the maximal possible sum of guests' conviviality ratings. InputEmployees are numbered from 1 to N. A first line of input contains a number N. 1 <= N <= 6 000. Each of the subsequent N lines contains the conviviality rating of the corresponding employee. Conviviality rating is an integer number in a range from -128 to 127. After that go T lines that describe a supervisor relation tree. Each line of the tree specification has the form:L KIt means that the K-th employee is an immediate supervisor of the L-th employee. Input is ended with the line 0 0OutputOutput should contain the maximal sum of guests' ratings.Sample Input711111111 32 36 47 44 53 50 0Sample Output5题意:一个公司要举办party,不过每一个员工都不愿意和自己的上级在一起,因为这样自己会不开心,而每个人参加party都有一个开心的程度,同时给出来上下级之间的关系,让我们求最大的开心程度是多少。
DP算法总结
1. 资源问题1-----机器分配问题f[i,j]:=max(f[i-1,k]+w[i,j-k]);2. 资源问题2------01背包问题f[i,j]:=max(f[i-1,j-v[i]]+w[i],f[i-1,j]);3. 线性动态规划1-----朴素最长非降子序列f[i]:=max{f[j]+1}4. 剖分问题1-----石子合并f[i,j]:=min(f[i,k]+f[k+1,j]+sum[i,j]);5. 剖分问题2-----多边形剖分f[i,j]:=min(f[i,k]+f[k,j]+a[k]*a[j]*a[i]);6. 剖分问题3------乘积最大f[i,j]:=max(f[k,j-1]*mult[k,i]);7. 资源问题3-----系统可靠性(完全背包)f[i,j]:=max{f[i-1,j-c[i]*k]*P[I,x]};8. 贪心的动态规划1-----快餐问题f[i,j,k]:=max{f[i-1,j',k']+(T[i]-(j-j')*p1-(k-k')*p2) div p3};9. 贪心的动态规划2-----过河f[i]=min{{f(i-k)} (not stone[i]){f(i-k)}+1} (stone[i]); +贪心压缩状态10. 剖分问题4-----多边形-讨论的动态规划F[i,j]:=max{正正f[I,k]*f[k+1,j];负负g[I,k]*f[k+1,j];正负g[I,k]*f[k+1,j];负正f[I,k]*g[k+1,j];} g为min11. 树型动态规划1-----加分二叉树(从两侧到根结点模型)F[i,j]:=max{f[i,k-1]*f[k+1,j]+c[k]};12. 树型动态规划2-----选课(多叉树转二叉树,自顶向下模型)f[i,j]表示以i为根节点选j门功课得到的最大学分f[i,j]:=max{f[t[i].l,k]+f[t[i].r,j-k-1]+c[i]};13. 计数问题1-----砝码称重f[f[0]+1]=f[j]+k*w[j];(1<=i<=n; 1<=j<=f[0]; 1<=k<=a[i];)14. 递推天地1------核电站问题f[-1]:=1; f[0]:=1;f[i]:=2*f[i-1]-f[i-1-m];15. 递推天地2------数的划分f[i,j]:=f[i-j,j]+f[i-1,j-1];16. 最大子矩阵1-----一最大01子矩阵f[i,j]:=min(f[i-1,j],v[i,j-1],v[i-1,j-1])+1;ans:=maxvalue(f);17. 判定性问题1-----能否被4整除g[1,0]:=true; g[1,1]:=false; g[1,2]:=false; g[1,3]:=false; g[i,j]:=g[i-1,k] and ((k+a[i,p]) mod 4 = j)18. 判定性问题2-----能否被k整除f[i,j±n[i] mod k]:=f[i-1,j]; -k<=j<=k; 1<=i<=n20. 线型动态规划2-----方块消除游戏f[i,i-1,0]:=0f[i,j,k]:=max{f[i,j-1,0]+sqr(len(j)+k), //dof[i,p,k+len[j]]+f[p+1,j-1,0] //not do}; ans:=f[1,m,0];21. 线型动态规划3-----最长公共子串,LCS问题f[i,j]=0 (i=0)&(j=0);f[i-1,j-1]+1 (i>0,j>0,x[i]=y[j]);max{f[i,j-1]+f[i-1,j]}} (i>0,j>0,x[i]<>y[j]);22. 最大子矩阵2-----最大带权01子矩阵O(n^2*m)枚举行的起始,压缩进数列,求最大字段和,遇0则清零23. 资源问题4-----装箱问题(判定性01背包)f[j]:=(f[j] or f[j-v[i]]);24. 数字三角形1-----朴素の数字三角形f[i,j]:=max(f[i+1,j]+a[I,j],f[i+1,j+1]+a[i,j]);25. 数字三角形2-----晴天小猪历险记之Hill同一阶段上暴力动态规划f[i,j]:=min(f[i,j-1],f[i,j+1],f[i-1,j],f[i-1,j-1])+a[i,j];26. 双向动态规划1数字三角形3-----小胖办证f[i,j]:=max(f[i-1,j]+a[i,j],f[i,j-1]+a[i,j],f[i,j+1]+a[i,j]);27. 数字三角形4-----过河卒//边界初始化f[i,j]:=f[i-1,j]+f[i,j-1];28. 数字三角形5-----朴素的打砖块f[i,j,k]:=max(f[i-1,j-k,p]+sum[i,k],f[i,j,k]);29. 数字三角形6-----优化的打砖块f[i,j,k]:=max{g[i-1,j-k,k-1]+sum[i,k]};30. 线性动态规划3-----打鼹鼠’f[i]:=f[j]+1;(abs(x[i]-x[j])+abs(y[i]-y[j])<=t[i]-t[j]);31. 树形动态规划3-----贪吃的九头龙f[i,j,k]:=min(f[x1,j1,1]+f[x2,j-j1-1,k]+d[k,1]*cost[i,fa[i]]] {Small Head}, f[x1,j1,0]+f[x2,j-j1,k]+d[k,0]*cost[i,fa[i]] {Big Head});f[0,0,k]:=0; f[0,j,k]:=max(j>0)d[i,j]:=1 if (i=1) and (j=1)1 if (i=0) and (j=0) and (M=2)0 else32. 状态压缩动态规划1-----炮兵阵地Max(f[Q*(r+1)+k],g[j]+num[k]);If (map[i] and plan[k]=0) and((plan[P] or plan[q]) and plan[k]=0);33. 递推天地3-----情书抄写员f[i]:=f[i-1]+k*f[i-2];34. 递推天地4-----错位排列f[i]:=(i-1)(f[i-2]+f[i-1]);f[n]:=n*f[n-1]+(-1)^(n-2);35. 递推天地5-----直线分平面最大区域数f[n]:=f[n-1]+n:=n*(n+1) div 2 + 1;36. 递推天地6-----折线分平面最大区域数f[n]:=(n-1)(2*n-1)+2*n;37. 递推天地7-----封闭曲线分平面最大区域数f[n]:=f[n-1]+2*(n-1);:=sqr(n)-n+2;38 递推天地8-----凸多边形分三角形方法数f[n]:=C(2*n-2,n-1) div n;对于k边形f[k]:=C(2*k-4,k-2) div (k-1); //(k>=3)39 递推天地9-----Catalan数列一般形式1,1,2,5,14,42,132f[n]:=C(2k,k) div (k+1);40 递推天地10-----彩灯布置排列组合中的环形染色问题f[n]:=f[n-1]*(m-2)+f[n-2]*(m-1); (f[1]:=m; f[2]:=m(m-1);41 线性动态规划4-----找数线性扫描sum:=f[i]+g[j];(if sum=Aim then getout; if sum<Aim then inc(i) else inc(j);)42 线性动态规划5-----隐形的翅膀min:=min{abs(w[i]/w[j]-gold)};if w[i]/w[j]<gold then inc(i) else inc(j);43 剖分问题5-----最大奖励f[i]:=max(f[i],f[j]+(sum[j]-sum[i])*i-t;44 最短路1-----Floydf[i,j]:=max(f[i,j],f[i,k]+f[k,j]);ans[q[i,j,k]]:=ans[q[i,j,k]]+s[i,q[i,j,k]]*s[q[i,j,k],j]/s[i,j];45 剖分问题6-----小H的小屋F[l,m,n]:=f[l-x,m-1,n-k]+S(x,k);46 计数问题2-----陨石的秘密(排列组合中的计数问题)Ans[l1,l2,l3,D]:=f[l1+1,l2,l3,D+1]-f[l1+1,l2,l3,D];F[l1,l2,l3,D]:=Sigma(f[o,p,q,d-1]*f[l1-o,l2-p,l3-q,d]);47 线性动态规划------合唱队形两次F[i]:=max{f[j]+1}+枚举中央结点48 资源问题------明明的预算方案:加花的动态规划f[i,j]:=max(f[i,j],f[l,j-v[i]-v[fb[i]]-v[fa[i]]]+v[i]*p[i]+v[fb[i]]*p[fb[i]]+v[fa[i]]*p[fa[i]]);49 资源问题-----化工场装箱员50 树形动态规划-----聚会的快乐f[i,2]:=max(f[i,0],f[i,1]);f[i,1]:=sigma(f[t[i]^.son,0]);f[i,0]:=sigma(f[t[i]^.son,3]);51 树形动态规划-----皇宫看守f[i,2]:=max(f[i,0],f[i,1]);f[i,1]:=sigma(f[t[i]^.son,0]);f[i,0]:=sigma(f[t[i]^.son,2]);52 递推天地-----盒子与球f[i,1]:=1;f[i,j]:=j*(f[i-1,j-1]+f[i-1,j]);53 双重动态规划-----有限的基因序列f[i]:=min{f[j]+1}g[c,i,j]:=(g[a,i,j] and g[b,i,j]) or (g[c,i,j]);54 最大子矩阵问题-----居住空间f[i,j,k]:=min(min(min(f[i-1,j,k],f[i,j-1,k]),min(f[i,j,k-1],f[i-1,j-1,k])),min(min(f[i-1,j,k-1],f[i,j-1,k-1] ),f[i-1,j-1,k-1]))+1;55 线性动态规划------日程安排f[i]:=max{f[j]}+P[I]; (e[j]<s[i])56 递推天地------组合数C[i,j]:=C[i-1,j]+C[i-1,j-1];C[i,0]:=157 树形动态规划-----有向树k中值问题F[I,r,k]:=max{max{f[l[i],I,j]+f[r[i],I,k-j-1]},f[f[l[i],r,j]+f[r[i],r,k-j]+w[I,r]]};58 树形动态规划-----CTSC 2001选课F[I,j]:=w[i](if i∈P)+f[l[i],k]+f[r[i],m-k](0≤k≤m)(if l[i]<>0);59 线性动态规划-----多重历史f[i,j]:=sigma{f[i-k,j-1]}(if checked);60 背包问题(+-1背包问题+回溯)-----CEOI1998 Substractf[i,j]:=f[i-1,j-a[i]] or f[i-1,j+a[i]];61 线性动态规划(字符串)-----NOI 2000 古城之谜f[i,1,1]:=min{f[i+length(s),2,1], f[i+length(s),1,1]+1};f[i,1,2]:=min{f[i+length(s),1,2]+words[s],f[i+length(s),1,2]+words[s]};62 线性动态规划-----最少单词个数f[i,j]:=max{f[i,j],f[u-1,j-1]+l};63 线型动态规划-----APIO2007 数据备份状态压缩+剪掉每个阶段j前j*2个状态和j*2+200后的状态贪心动态规划f[i]:=min(g[i-2]+s[i],f[i-1]);64 树形动态规划-----APIO2007 风铃f[i]:=f[l]+f[r]+{1 (if c[l]<c[r])};g[i]:=1(d[l]<>d[r]) 0(d[l]=d[r]);g[l]=g[r]=1 then Halt;65 地图动态规划-----NOI 2005 adv19910F[t,i,j]:=max{f[t-1,i-dx[d[[t]],j-dy[d[k]]]+1],f[t-1,i,j];66 地图动态规划-----优化的NOI 2005 adv19910F[k,i,j]:=max{f[k-1,i,p]+1} j-b[k]<=p<=j;67 目标动态规划-----CEOI98 subtraF[I,j]:=f[I-1,j+a[i]] or f[i-1,j-a[i]];68 目标动态规划----- Vijos 1037搭建双塔问题F[value,delta]:=g[value+a[i],delta+a[i]] or g[value,delta-a[i]];69 树形动态规划-----有线电视网f[i,p]:=max(f[i,p],f[i,p-q]+f[j,q]-map[i,j]);leaves[i]>=p>=l, 1<=q<=p;70 地图动态规划-----vijos某题F[i,j]:=min(f[i-1,j-1],f[i,j-1],f[i-1,j]);71 最大子矩阵问题-----最大字段和问题f[i]:=max(f[i-1]+b[i],b[i]); f[1]:=b[1];72 最大子矩阵问题-----最大子立方体问题枚举一组边i的起始,压缩进矩阵B[I,j]+=a[x,I,j];枚举另外一组边的其实,做最大子矩阵73 括号序列-----线型动态规划f[i,j]:=min(f[i,j],f[i+1,j-1] (s[i]s[j]=”()”or(”[]”)),f[i+1,j+1]+1 (s[j]=”(”or”[” ) , f[i,j-1]+1(s[j]=”)”or”]”);74 棋盘切割-----线型动态规划f[k,x1,y1,x2,y2]=min{min{f[k-1,x1,y1,a,y2]+s[a+1,y1,x2,y2],f[k-1,a+1,y1,x2,y2]+s[x1,y1,a,y2]};75 概率动态规划-----聪聪和可可(NOI2005)x:=p[p[i,j],j];f[I,j]:=(f[x,b[j,k]]+f[x,j])/(l[j]+1)+1;f[I,i]=0;f[x,j]=1;76 概率动态规划-----血缘关系F[A, B]=(f[A0, B]+P[A1, B])/2;f[i,i]=1;f[i,j]=0;(i,j无相同基因)77 线性动态规划-----决斗F[i,j]=(f[i,j] and f[k,j]) and (e[i,k] or e[j,k]); (i<k<j)78 线性动态规划-----舞蹈家F[x,y,k]=min(f[a[k],y,k+1]+w[x,a[k]],f[x,a[k],k+1]+w[y,a[k]]);79 线性动态规划-----积木游戏F[i,a,b,k]=max(f[a+1,b,k],f[i+1,a+1,a+1,k],f[i,a+1,a+1,k]);80 树形动态规划(双次记录)-----NOI2003 逃学的小孩朴素的话枚举节点i和离其最远的两个节点j,k O(n^2)每个节点记录最大的两个值,并记录这最大值分别是从哪个相邻节点传过来的。
2024年学整树学习心得范本(2篇)
2024年学整树学习心得范本整树学习是一种全面系统的学习方法,它以树状结构的形式展示和组织知识,使学习者能够系统地掌握知识,并深入理解知识之间的联系。
在我接触整树学习这一概念之后,我深深被其独特的学习方式和理念所吸引,于是开始了我自己的整树学习之旅。
在这个过程中,我不仅加深了对知识本身的理解,还提高了自己的学习能力和思维水平。
下面是我在整树学习中的一些心得体会。
首先,整树学习强调对知识的全面了解。
每个知识点都是整棵树的一部分,它们之间相互联系,相互依赖。
如果我们只关注树的一部分,而忽视了其他部分,那么对这个领域的理解就是片面的、不全面的。
因此,在进行整树学习时,我始终保持着对整个知识体系的关注和学习。
我会先构建一个完整的知识框架,然后逐个填充知识点,逐步完善和深化我的理解。
其次,整树学习培养了我系统思考的能力。
整树学习的核心思想是将知识以树状结构的方式展示出来,这要求我们能够将看似零散的知识点组织起来,形成一个有机的整体。
在实践中,我学会了将不同的知识点归类、梳理,将它们按照一定的逻辑关系连接起来。
通过这个过程,我不仅理顺了知识的脉络,还培养了自己的系统思考能力,从而能够更好地解决问题和应对挑战。
第三,整树学习注重对知识的深入理解。
整树学习的目的是追求对知识的深入理解,而不仅仅是简单地记住一些表面知识。
在我的整树学习中,我注重通过反复学习和思考,透彻地理解和消化知识。
我不满足于只会应对考试,而是追求对知识的真正掌握。
这种深度的理解让我能够更好地运用和应用知识,同时也提高了我的学习效果。
第四,整树学习拓宽了我的知识面。
整树学习要求我们对一个领域的知识有全面、系统的了解,这就要求我们不仅要学习该领域的核心知识,还要拓展到相关领域。
在我的整树学习中,我经常会不断地寻找和学习与当前知识相关的其他知识,从而扩大了我的知识面。
这使我能够更好地处理复杂的问题,并在实践中得到更好的应用。
第五,整树学习提高了我的学习效率。
状态压缩DP小结
状态压缩DP小结最近做了一些状态压缩的动态规划题目,写点感想吧。
FZU1025 Mondriaan’s Dream这道题我认为应该是最基础的状态压缩DP的题目了,所以写详细一点。
题目大意:给出一个矩形的长和宽,求这个矩形用1*2或2*1的方格填满,有多少种放置的方法。
由于长和宽均小于等于11,故每一行均可用一个2进制数表示其状态。
我们用1表示竖放的方格,0表示横放的方格。
那么样例中各行的状态分别为:00100001100111100111001111001100100111001001100110000111000000111100001001100100111001001001110011100001000011转化为十进制,就是268,1948,1945,457,1219,1039,76,1252,1255,67。
用f(i,j)表示第i行状态为j时,有多少种排法。
那么f(i,j)应该等于前i-1行,状态k与j相符的排法数的和。
状态相符,即在j二进制数上为1的位,k一定也为1。
在向下递归时,应该把k中和j二进制状态中同为1的位置为0,即应该求f(i-1,k^j),原因是当第i-1行与第i行相接后,二者同为1的地方消掉了,应该当作0处理。
所以f(i,j)=sigma(f(i-1,k^j),(k^j)==k-j&&check(k)(check(k)表示k是有效的行状态,即二进制数状态中连续的0个数为偶数,可先生成存入数组中)。
所求答案即为f(n,0),初始化f(0,i)=0,f(0,0)=1。
注意结果要用long long或__int64保存,还有要注意位运算的优先级是很低的。
P.S:据说这道题有公式。
PKU1185 炮兵阵地这道题是中文题,意思很容易理解,就不说明题意了。
由于M很小,最多为10,所以可以对行进行状态压缩。
二进制对应位为1表示放炮兵,为0表示空。
我们可以事先生成所有有效的状态,即二进制数任何两个1都要相差两位以上,同时用数组记下此状态有多少个炮兵。
树状DP与状态压缩DP.
例题一:HDU 2412 PARTY AT HALI-BULA
题目大意: n个人形成一个关系树,每个节点代表一个人,节点的根表 示这个人的唯一的直接上司,只有根没有上司。要求选取一 部分人出来,使得每2个人之间不能有直接的上下级的关系, 求最多能选多少个人出来,并且求出获得最大人数的选人方 案是否唯一。 这是一个经典的树型动态规划。 状态? 转移?
1.2 PARTY AT HALI-BULA
简单的染色统计是不正确的
1.3 PARTY AT HALI-BULA
人之间的关系形成树型结构 DP, 用dp[i][0]表示不选择i点时,i点及其子树能选出 的最多人数,dp[i][1]表示选择i点时,i点及其子树的 最多人数。
1.4 PARTY AT HALI-BULA
状态转移方程:
对于叶子节点 dp[k][0] = 0, dp[k][1] = 1 对于非叶子节点i, dp[i][0] = ∑max(dp[ j][0], dp[ j][1]) ( j是i的儿子) dp[i][1] = 1 + ∑dp[ j][0] ( j是i的儿子)
最多人数即为max(dp[0][0], dp[0][1])
3.2 基础回顾
树的中序遍历
若二叉树为空则结束返回, 否则: (1)中序遍历左子树。 (2)访问根结点。 (3)中序遍历右子否则:
(1)访问根结点. (2)前序遍历左子树. (3)前序遍历右子树 .
3.3 样例
3.4 分析
本题适合用动态规划来解。如果用数组value[i,j]表示 从节点i到节点j所组成的二叉树的最大加分,则动态 方程可以表示如下: value[i,j]=max{value[i,i]+value[i+1,j], value[k,k]+value[i,k]*value[k+1,j] | i<k<j, value[i,j-1] + value[ j,j] };
树形dp与优化方法
输入数据示例
输出数据示例 25
问题分析
求给定的带权树的符合下面条件的子顶点集合V:
1. 若点i∈V,则所有与i相邻的点j可被标号。 2. 任意一个点j,若j不属于V,则j可被标号。 3. S=∑(Weight[i],i∈V),并且S最小。
考虑到树本身的特性:除了根节点外,每一个节点 都仅与该节点的父节点与儿子节点有关系;大多数 情况下,每个节点的状况都是由它的儿子节点的状 况决定的。这与动态规划的无后效性要求相符,再 加上本题求的又是最优方案,这一切都与动态规划 算法不谋而合。
要求覆盖以节点i为顶点的树的最佳方案Vi, 显然只需考虑节点i属于或不属于集合V两种 情况,两者择优即可。即Vi=min{Vi1,Vi2} (1表示属于,2表示不属于)
(一)若i∈V,则对于i的任一儿子j,也只 有属于或不属于集合V两种情况:
(1)若j∈V,则问题转化到求Vj1的 小一级规模问题,转化成功; (2) 若j不属于V,则要不求Vj2,要 不就是j不能被j的任意一个儿子标号,则 求所有Vk(k为j的儿子),Vi1求好了。
【输入】 第一行一个整数N(N<100)。接下来有N 行,每一行描述一个人的信息,信息之间用 空格隔开。姓名是长度不超过20的字符 串,幽默系数是在0到100之间的整数。 【输出】 所邀请的人最大的幽默系数和。
【样例】 party.in party.out 5 8 BART 1 HOMER HOMER 2 MONTGOMERY MONTGOMERY 1 NOBODY LISA 3 HOMER SMITHERS 4 MONTGOMERY
(二)若i不属于V,i一定要能被i的某个儿子j 标号,这时求所有Vj(j为i的儿子)。若所有的 j都是j被j的儿子标号时最“省”(即所有Vj= Vj2),那么实际上按这样的方案没有一个j∈V, 造成了i不能被标号。 这时只要找一个"牺牲"最小的i的儿子j,把 方案Vj2换成Vj1。这样就求出了"覆盖以节点i 为顶点且不包括节点i的最佳节点集Vi2"。
树实践活动总结7篇
树实践活动总结7篇(经典版)编制人:__________________审核人:__________________审批人:__________________编制单位:__________________编制时间:____年____月____日序言下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。
文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!并且,本店铺为大家提供各种类型的经典范文,如述职报告、调研报告、策划方案、活动方案、心得体会、应急预案、规章制度、教学资料、作文大全、其他范文等等,想了解不同范文格式和写法,敬请关注!Download tips: This document is carefully compiled by this editor. I hope that after you download it, it can help you solve practical problems. The document can be customized and modified after downloading, please adjust and use it according to actual needs, thank you!Moreover, our store provides various types of classic sample essays, such as job reports, research reports, planning plans, activity plans, personal experiences, emergency plans, rules and regulations, teaching materials, complete essays, and other sample essays. If you want to learn about different sample formats and writing methods, please pay attention!树实践活动总结7篇活动总结可以提高组织者的决策水平,减少在活动执行中的盲目性,活动总结有助于加深自己对组织使命和愿景的认同感,下面是本店铺为您分享的树实践活动总结7篇,感谢您的参阅。
树形DP之个人整理总结
#include<iostream> #include<vector> #include<limits> using namespace std; #define MN 110 int f[2*MN],p[MN],tmp[MN];
第 1页
Auther: 陈江勇 2008 年 10 月 22 日
树形 DP
通常我们状态转移的时候是枚举每个子状态的, 但是这里我们还得用一个 DP 来枚举子状态。
假设一个节点 i 有 n 个子节点,那么求 f(i,k) 时就要考虑怎么把 k 分到 n 个节点上使得盈利
最大。
下面关键是如何去枚举:
如果节点 i 有 X 个子结点设为 1~~X ,假如当前 DP 算到第 j( 0=<j<=X )个节点 ,第 j 个节点
N and M (1 ≤ M < N; 1 < N ≤ 100)
input 52 131 1 4 10 2 3 20 3 5 20 output 21
算法: 删除了某个分支,那么这个分支下的子分支也同时删除。 保留 M 个分支,也就是删除 N-M-1 个分支。剩余的最多苹果数 =总苹果数 -剪掉的苹果数。 注意本题给的边并没有按照树根 -- 树叶的形式来给,也没有按照树的顺序给出边。本来想一 个节点对应一个分支长着的苹果数量, cost[v] 就表示 v 这个节点的苹果数,可以这样做,但 是在输入的时候, 不知道这个苹果数量是那个节点的, 因为不知道哪个是哪个的子结点。 所 以用了无向图和苹果数加到边上去。 我的解法中:这题的树状 DP 的整体思想个 pku3345 是一样的。 有一些不一样的地方要注意一下: 本程序其实不仅仅针对二叉树,可以是任意的树,删除任意个分支都有算。
DP_树形DP专辑
树,一种十分优美的数据结构,因为它本身就具有的递归性,所以它和子树见能相互传递很多信息,还因为它作为被限制的图在上面可进行的操作更多,所以各种用于不同地方的树都出现了,二叉树、三叉树、静态搜索树、AVL树,线段树、SPLAY树,后缀树等等..枚举那么多种数据结构只是想说树方面的内容相当多,本专辑只针对在树上的动态规划,即树形DP.做树形DP一般步骤是先将树转换为有根树,然后在树上进行深搜操作,从子节点或子树中返回信息层层往上更新至根节点。
这里面的关键就是返回的信息部分,这个也没一般性的东西可讲,因为每道题目要求做的事都不尽相同。
这个专辑暂时氛围3哥部分,分的可能不是很好,后面题目做多了理解更深了可能会更改,但那都是后话了。
一、常规树形DP1、Hdu 1520 Anniversary party每个节点有权值,子节点和父节点不能同时选,问最后能选的最大价值是多少?解题报告Here2、Hdu 2196 Computer经典题,求树每个点到其他点的最远距离,转化为有根树,深搜两次,一次记录到叶子的最远距离,一次更新最终答案。
解题报告Here3、Poj 1741 Tree(难) 经典题,求树上两点间距离小等于K的方案数,树上分治。
解题报告Here4、Poj 2152 Fire(难)罕见的O(n^2)的树形DP,在树上建消防站,要求每个节点离最近的消防站距离小于K,问最小花费。
解题报告Here5、Poj 3162 Walking Race(难)树形DP找最远距离+线段树查询最大最小值,然后再维护两个指针遍历整个序列。
解题报告Here6、cf 218D. Choosing Capital for Treeland 把边方向转变成边权,正向为0,反向为1.经过转换,问题变成求某点为根到所有点的边权总和,求边权总和最小的那些点。
二、树形背包问题(在树上进行分组背包处理)1、Poj 1155 TELE把每个节点的子节点看成一组背包,最大容量是这点的叶子子孙数量,选几个节点就是选择的容量,价值就是用户给的Money-中转费用。
树型DP
后序遍历
compute(x)//计算以x为根的子树的最优值 Var i:integer;//i必须是局部变量,即x私有 Begin for i=1 to maxson(x) do compute(son(x,i)); 确定f(x) end; //i(只)被用来枚举所有儿子,若i为全局变量,则子孙可能改变i,显然这是 不允许的 理解: 设你是父亲,你把工作分给你的儿子去做 你等所有儿子都完成后,返回到你,你再捡现成,确定 你的最优值f(x) 上面这个子程序几乎是所有树型DP的框架。 延伸:DP的记忆化搜索也是一个后序遍历,先让儿子做事,最后父亲捡现成。
树的遍历
• 完全理解并能熟练应用 • 知道一棵二叉树的先序和中序遍历序列,求后 序遍历 • 先序遍历:
– XLR – 先序遍历的特点:先输出根,再输出所有左子树 的节点,最后输出右了树的所有节点 L
x
R
树由根和子树组成 子树是树
• 中序遍历:
– LXR – 中序遍历的特点:先输出所有左子树的节点,再 输出根,最后输出右了树的所有节点
已知前中序,求后序
难点
• 存储方式
– 顺序结构(数组) – 简单,但是浪费空间,
• 当树的规模较大,顺序结构就无能为力了 • 链表 • 多叉转二叉
– 左儿子右兄弟
练习
• 红书p156
– 指针操作 – 找根
• 树的中心
– (p162)(没有父亲) 该题标程使用了数学方法,1+2+3+…+n=(n*(n+1))/2 每读入一条边(a的父亲为b),把a加到root中,表示a不能作为根了 最后(n*(n+1))/2-所有不能作父亲的节点的和=根
树由根和子树组成子树是树子树的实际遍历过程很复杂但你不用想那么子树的实际遍历过程很复杂但你不用想那么多那是你儿子的事它自然会完成并向你返多那是你儿子的事它自然会完成并向你返回的
Codeforces1179D树形DP斜率优化
Codeforces1179D树形DP斜率优化题意:给你⼀颗树,你可以在树上添加⼀条边,问添加⼀条边之后的简单路径最多有多少条?简单路径是指路径中的点只没有重复。
思路:添加⼀条边之后,树变成了基环树。
容易发现,以基环上的点为根的⼦树的点中的简单路径没有增加。
所以,问题相当于转化为找⼀个基环,使得以基环上的点为根的⼦树Σ(i从1到n) sz[i] * (sz[i] - 1) / 2最⼩。
我们把式⼦转化⼀下变成求(sz[i]的平⽅和 - n) / 2。
相当于我们需要求sz[i]的平⽅和。
但是,我们并不知道哪个是基环,怎么求sz呢?我们发现⼀个性质:添加的边连接的两点⼀定是树中度数为1的点,否则,我们⼀定可以缩⼩平⽅和。
所以,根据这个性质,我们可以进⾏树形dp。
设dp[i]为以i为根的⼦树中,选择从i到⼦树中的某个叶⼦节点的路径为基环上的点,可以获得的最⼩的平⽅和。
dp[i] = min(dp[son] + (sz[i] - sz[son]) ^ 2)。
我们假设选择的基环是u -> lca(u, v) -> v ,假设fu为u到lca(u, v)的路径中lca(u, v)的前⾯⼀个节点,fv同理,那么平⽅和为ans = dp[fu] + dp[fv] + (n - sz[fu] - sz[fv]) ^ 2。
所以,我们在深搜的时候,找到所有孩⼦的dp值和sz,枚举是哪两个孩⼦来更新平⽅和,这样最坏情况是O(n ^ 2)的,会超时。
发现状态转移⽅程中有fu和fv的乘积项,我们可以考虑斜率优化。
把⽅程移项: dp[fv] = 2 * (n - sz[fu]) * sz[fv] + (ans - dp[fu] - 2 * n * sz[fu])。
那么相当于是以sz[fv]为横坐标,dp[fv]为纵坐标,斜率为2 * (n - sz[fu])的直线,要ans最⼩,需要截距最⼩。
我们把sz从⼩到⼤排序,⽤单调队列维护⼀个下凸包,之后在单调队列⾥⼆分即可。
poj3107(树的重心,树形dp)
poj3107(树的重⼼,树形dp)题⽬链接:https:///problem/POJ-3107题意:求树的可能的重⼼,升序输出。
思路:因为学树形dp之前学过点分治了,⽽点分治的前提是求树的重⼼,所以这题就简单⽔了⼀下。
⽤sz[u]记录⼦树u的⼤⼩,son[u]记录以u为根时,⼦结点中最⼤的结点数。
所以: son[u]=max(son[v],n-sz[u]),前⼀部分son[v]好理解,对于n-sz[u],即结点u的⽗结点那⼀块的⼤⼩。
AC code:#include<cstdio>#include<algorithm>using namespace std;const int maxn=50005;int n,cnt,head[maxn],sz[maxn],son[maxn];struct node1{int v,nex;}edge[maxn<<1];struct node2{int val,id;}ans[maxn];void adde(int u,int v){edge[++cnt].v=v;edge[cnt].nex=head[u];head[u]=cnt;}bool cmp(node2 a,node2 b){if(a.val==b.val) return a.id<b.id;return a.val<b.val;}void getroot(int u,int fa){sz[u]=1,son[u]=0;for(int i=head[u];i;i=edge[i].nex){int v=edge[i].v;if(v==fa) continue;getroot(v,u);sz[u]+=sz[v];son[u]=max(son[u],sz[v]);}son[u]=max(son[u],n-sz[u]);ans[u].val=son[u],ans[u].id=u;}int main(){scanf("%d",&n);for(int i=1;i<n;++i){int u,v;scanf("%d%d",&u,&v);adde(u,v);adde(v,u);}getroot(1,0);sort(ans+1,ans+n+1,cmp);printf("%d",ans[1].id);for(int i=2;i<=n&&ans[i].val==ans[1].val;++i)printf(" %d",ans[i].id);printf("\n");return0;}。
园林树木学个人总结
名词解释:1.乔木:树体高大,有直立发达的主干,主侧枝分布明显的树干。
2.灌木: 没有明显主干,由地面分出多数枝条或虽具主干而高度不超过5m的树木。
3.秋色叶树:在秋季叶子有显著变化的树种,称为“秋色叶树”。
4.乡土树种:本地区原有天然分布的树种。
指与当地自然条件,尤其是气候、土壤条件达到稳定平衡,对原产的环境具有天然适应性的树种。
5.庭荫树:主要用以形成绿荫供游人纳闵避免日光曝晒,也能起到装饰作用的树种。
6.园林树木学:以园林建设为宗旨,对园林树木的分类、习性、繁殖、栽培管理和应用等方面进行系统研究的学科称园林树木学。
7. 营养生长期:从种子萌发为幼苗,长出根、茎、叶的过程。
8.园林树木年周期:植物在一年中经过的生活周期称年周期。
9. 种: 是自然界中客观存在的一种类群。
这种类群的所有个体都有着极其近似的形态特征和生理、生态特性,个体间可以自然交配产生正常后代而使种族延续,它们在自然界中又占有一定的分布区域。
10.丛植:由三株至十株同种或异种的树木种植在一起、形成林冠线彼此密接的种植方式11.花序:花在枝条上的排列方式。
12.常绿树种:当年新生叶当年不脱落的树种,叶片寿命长于一年13. 园林树木:适于城乡各类园林绿地、风景名胜、森林公园、休疗养伤及居住地区栽植应用的木本植物。
14.顶端优势:一个近于直立的枝条,其顶端的芽能抽生最强的新梢,而侧芽所抽生的枝,其生长势多呈自上而下递减的趋势,最下部的一些芽则不萌发。
这种顶部分生组织或茎尖对其下芽萌发力的抑制作用,叫做“顶端优势”。
15.自然休眠:亦称深休眠或熟休眠,是由于树木生理过程所引起的或由树木遗传特性所决定的,落叶树木进入自然休眠后,要在一定的低温条件下经过一段时间后才能结束。
未通过时,即使给予适合生长的外界条件,也不能萌芽生长。
16.叶痕:叶脱落后,叶柄基部在小枝上留下的痕迹。
17.复叶:总叶柄具2片以上分离的叶片。
18.观赏树木:泛指一切可供观赏的木本植物,包括各种乔木、灌木、木质藤本以及竹类。
DP总结_翁家翌
转移方式
DP 优化
Tsinghua University 9 / 45
状态类型 坐标 dp
共性总结
转移方式
DP 优化
• 状态是由坐标维与其他的维组成. • 划分问题 (2 维或多维的坐标系的划分) 与路径问题的交集占
本类问题中大多数. • 找坐标状态之间的关系: Apio2009-oil
状态类型 数轴 dp
Problems
转移方式
1 01 背包: 将 Value 作为 dp 的状态
• 有时候可以用 bitset 优化 • 装箱问题、币值分割、…… • 1304 • 听说排序后有惊喜? • 剩余系下跑 spfa: BZOJ2118
2 博弈论:与 SG 函数结合
n+e DP
DP 优化
n+e DP
Tsinghua University 7 / 45
状态类型 区间 dp
Problems
转移方式
DP 优化
• f[l][r] 表示一段连续区间 [l, r ] 上的答案
1 序列: 区间 [l, r ] 的最后一步处理的是 k 元素 / 分割点是 k / 受 k 控制的 常用四边形不等式优化
影响 3 有些可以直接转换为数学问题, 考察数学功底
n+e DP
Tsinghua University 24 / 45
状态类型 划分问题: 求一系列的分割/合并点
1 状态类型
转移方式
2 转移方式 递推 划分问题: 求一系列的分割/合并点
决策的分割点有序 决策的分割点无序
路径问题
3 DP 优化
n+e DP
DP 优化
Tsinghua University 25 / 45
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
树形DP二叉苹果树(ural 1108)题目意思:有一棵苹果树,苹果树的是一棵二叉树,共N个节点,树节点编号为1~N,编号为1的节点为树根,边可理解为树的分枝,每个分支都长着若干个苹果,现在要要求减去若干个分支,保留M个分支,要求这M个分支的苹果数量最多。
输入:N M接下来的N-1行是树的边,和该边的苹果数N and M (1 ≤ M < N; 1 < N ≤ 100)输出:剩余苹果的最大数量。
input5 21 3 11 4 102 3 203 5 20output21算法:删除了某个分支,那么这个分支下的子分支也同时删除。
保留M个分支,也就是删除N-M-1个分支。
剩余的最多苹果数=总苹果数-剪掉的苹果数。
注意本题给的边并没有按照树根--树叶的形式来给,也没有按照树的顺序给出边。
本来想一个节点对应一个分支长着的苹果数量,cost[v]就表示v这个节点的苹果数,可以这样做,但是在输入的时候,不知道这个苹果数量是那个节点的,因为不知道哪个是哪个的子结点。
所以用了无向图和苹果数加到边上去。
我的解法中:这题的树状DP的整体思想个pku3345是一样的。
有一些不一样的地方要注意一下:本程序其实不仅仅针对二叉树,可以是任意的树,删除任意个分支都有算。
#include<iostream>#include<vector>#include<limits>using namespace std;#define MN 110int f[2*MN],p[MN],tmp[MN];int N,M;bool visit[MN];struct NODE{int val;int cost;};vector<NODE>G[MN];inline int max(int a,int b){return a>b?a:b;}inline int min(int a,int b){return a<b?a:b;}void my_clear(){int i;for(i=0;i<=N;i++){G[i].clear();}memset(visit,false,sizeof(visit));}int DP(int v,int from){visit[v]=true;int i,j,k,s,w,last,now;s=G[v].size();if(s==1) //这边不再是s==0{p[0]=0;return 1;}last=0;f[from]=0;for(i=0;i<s;i++){w=G[v][i].val;if(visit[w]==true)continue;now=DP(w,from+last+1);p[now]=p[now-1]+G[v][i].cost; //这边不要漏,把节点w也给删除for(j=0;j<=last+now;j++)tmp[j]=INT_MAX;for(j=0;j<=last;j++){for(k=0;k<=now;k++){tmp[j+k]=min(tmp[j+k],f[from+j]+p[k]);}}last+=now;for(j=0;j<=last;j++){f[from+j]=tmp[j];}}for(i=0;i<=last;i++)p[i]=f[i+from];last++; //加上自身节点return last;}int main(){int i,a,b,sum,c;NODE tmp;while(scanf("%d%d",&N,&M)!=EOF){sum=0;my_clear();for(i=1;i<N;i++){scanf("%d%d%d",&a,&b,&c);tmp.cost=c;tmp.val=b;G[a].push_back(tmp);tmp.val=a;G[b].push_back(tmp);sum+=c;}DP(1,0);printf("%d\n",sum-f[N-M-1]);}return 0;}有限电视网络(pku1155 TELE)题目描述:有一个电视台要用电视网络转播节目。
这种电视网络是一树,树的节点为中转站或者用户。
树节点的编号为1~N,其中1为总站,2~(N-M)为中转站,(总站和中转站统称为转发站)N-M+1~N为用户,电视节目从一个地方传到另一个地方都要费用,同时每一个用户愿意出相应的钱来付电视节目。
现在的问题是,在电视台不亏本的前提下,要你求最多允许有多少个用户可以看到电视节目。
输入:N M N表示转发站和用户总数,M为用户数以下N-M行,第i行第一个K,表示转发站i和K个(转发站或用户)相连, 其后第j对数val,cost表示,第i个转发站到val有边,费用cost.最后一行M个数表示每个用户愿意负的钱。
输出:不亏本前提下,可以收到节目最多的用户数。
(如果某个用户要收到节目(叶子结点),那么电视台到该用户的路径节点的费用都要付)Sample Input9 63 2 2 3 2 9 32 4 2 5 23 6 2 7 2 8 24 3 3 3 1 1Sample Output5算法:这是一道树状态DP.状态f(n,k)表示第n个节点发送给k个用户最多能盈利多少,k不超过n所管辖的叶节点个数。
那么答案就是使f(root,k)>=0最大的k了。
通常我们状态转移的时候是枚举每个子状态的,但是这里我们还得用一个DP来枚举子状态。
假设一个节点i有n个子节点,那么求f(i,k)时就要考虑怎么把k分到n个节点上使得盈利最大。
下面关键是如何去枚举:如果节点i有X个子结点设为1~~X,假如当前DP算到第j(0=<j<=X)个节点,第j个节点有now个用户,而0~j-1共有last用户,f[i][k]=max(f[i][k],f[i][a]+f[j][b])(其中a+b=k,0=<k<=last+now); f[i][a]表示把a个用户分配给0~~j-1节点,分配b个用户给j这个节点。
本程序用写了另外一个用滚动数组来省空间的方法,注意多了一个参数from,否则原来的值会被覆盖掉。
#include<iostream>#include<limits>#include<vector>using namespace std;int N,M;vector<int>G[3001];int money[3001],cost[3001],p[3001],f[6001],tmp[3001];void my_clear(){int i;for(i=0;i<=N;i++){G[i].clear();}}int DP(int v,int from){int i,s,last,now,k,j,w;s=G[v].size();if(!s){p[0]=0;p[1]=money[v-N+M];return 1;}last=0;f[from]=0;for(i=0;i<s;i++){w=G[v][i];now=DP(w,from+last+1);for(j=0;j<=last+now;j++){tmp[j]=INT_MIN;}for(j=1;j<=now;j++){p[j]-=cost[w];}for(j=0;j<=last;j++){for(k=0;k<=now;k++){if(f[from+j]+p[k]>tmp[j+k]){tmp[j+k]=f[from+j]+p[k];}}}tmp[0]=0;last+=now;for(j=0;j<=last;j++){f[j+from]=tmp[j];}}/* printf("%d\n",v);for(i=0;i<=last;i++){printf("%d %d\n",i,f[i+from]);}*/for(j=0;j<=last;j++)p[j]=f[j+from];return last;}int main(){int i,K,j,b;scanf("%d%d",&N,&M);my_clear();for(i=1;i<=N-M;i++){scanf("%d",&K);for(j=0;j<K;j++){scanf("%d",&b);scanf("%d",&cost[b]);G[i].push_back(b);}}for(i=1;i<=M;i++)scanf("%d",&money[i]);DP(1,0);for(i=M;i>=0;i--){if(f[i]>=0)break;}printf("%d\n",i);return 0;}最少步数摘最多的苹果(pku2486 Apple Tree)DescriptionWshxzt is a lovely girl. She likes apple very much. One day HX takes her to an apple tree. There are N nodes in the tree. Each node has an amount of apples. Wshxzt starts her happy trip at one node. She can eat up all the apples in the nodes she reaches. HX is a kind guy. He knows that eating too many can make the lov ely girl become fat. So he doesn’t allow Wshxzt to go more than K steps in the tree. It costs one step when she goes from one node to another adjacent node. Wshxzt likes apple very much. So she wants to eat as many as she can. Can you tell how many apples she can eat in at most K steps.InputThere are several test cases in the inputEach test case contains three parts.The first part is two numbers N K, whose meanings we have talked about just now. We denote the nodes by 1 2 ... N. Since it is a tree, each node can reach any other in only one route. (1<=N<=100, 0<=K<=200)The second part contains N integers (All integers are nonnegative and not bigger than 1000). The ith number is the amount of apples in Node i.The third part contains N-1 line. There are two numbers A,B in each line, meaning that Node A and Node B are adjacent.Input will be ended by the end of file.Note: Wshxzt starts at Node 1.OutputFor each test case, output the maximal numbers of apples Wshxzt can eat at a line.Sample Input2 10 111 23 20 1 21 21 3Sample Output112f[i][j][0]保存对于节点i向其子树走j步(可能有点重复)摘到的最多苹果数f[i][j][1]保存对于节点i向其子树走j步并且返回到i节点摘到的最多苹果数对于叶节点f[i][0][0/1]=apNum[i];对于其它节点f[i][j][0]=max{j-2*p-1步,其中p个子树返回,1个子树不需要返回,所得到最多苹果数,p不定};f[i][j][1]=max{j-2*p步,p个子树都返回,所得到的最多苹果数,p不定}这两步中间过程都需要DP 复杂度=j*子树个数(<n)那么最终结果就是f[1][k][0]整个大的DP时间复杂度<n*(k*n)<2*10^6树型DP中套小DP*/#include<iostream>#include<vector>using namespace std;#define MN 101int back[201][201],go[201][201],num[101],t1[201],t2[201];vector<int>G[MN];int N,K;inline int max(int a,int b){return a>b?a:b;}void my_clear(){int i;for(i=0;i<=N;i++){G[i].clear();}memset(go,0,sizeof(go));memset(back,0,sizeof(back));}void DP(int v,int p){int i,s,w,j,m,n;s=G[v].size();for(i=0;i<s;i++){w=G[v][i];if(w==p)continue;DP(w,v);back[w][0]=0;back[w][1]=0;go[w][0]=0;for(j=K;j>=2;j--){back[w][j]=back[w][j-2]+num[w];}for(j=K;j>=1;j--){go[w][j]=go[w][j-1]+num[w];}memset(t1,0,sizeof(t1));memset(t2,0,sizeof(t2));for(m=0;m<=K;m++){for(n=0;n<=m;n++){t1[m]=max(t1[m],back[v][n]+back[w][m-n]);t2[m]=max(t2[m],max(go[v][n]+back[w][m-n],back[v][n]+go[w][m-n]));}}for(j=0;j<=K;j++){back[v][j]=t1[j];go[v][j]=t2[j];}}}int main(){int a,b;while(scanf("%d%d",&N,&K)!=EOF){int i;for(i=1;i<=N;i++)scanf("%d",&num[i]);my_clear();for(i=1;i<N;i++){scanf("%d%d",&a,&b);G[a].push_back(b);G[b].push_back(a);}DP(1,0);int ans=max(go[1][K],back[1][K]);ans+=num[1];printf("%d\n",ans);}return 0;}钻石总统(pku3345 Bribing FIPA)题目大意:有个人要竞选某职务,有N个国家参选,他想通过贿赂某些国家来赢得这个国家的选票,每个国家都要花费相应的钻石才可以被贿赂。