树形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都要相差两位以上,同时用数组记下此状态有多少个炮兵。
- 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个国家参选,他想通过贿赂某些国家来赢得这个国家的选票,每个国家都要花费相应的钻石才可以被贿赂。