树形动态规划讲解

合集下载

树型动态规划(C++版)

树型动态规划(C++版)

树型动态规划补充二叉树的遍历的相关知识:在二叉树的应用中,常常要求在树中查找具有某种特征的结点,或者对全部结点逐一进行某种处理。

这就是二叉树的遍历问题。

所谓二叉树的遍历是指按一定的规律和次序访问树中的各个结点,而且每个结点仅被访问一次。

“访问”的含义很广,可以是对结点作各种处理,如输出结点的信息等。

遍历一般按照从左到右的顺序,共有3 种遍历方法,先(根)序遍历,中(根)序遍历,后(根)序遍历。

先序遍历的操作定义如下:若二叉树为空,则空操作,否则①访问根结点②先序遍历左子树③先序遍历右子树先序遍历右图结果为:124753689中序遍历的操作定义如下:若二叉树为空,则空操作,否则①中序遍历左子树②访问根结点③中序遍历右子树中序遍历右图结果为:742513869后序遍历的操作定义如下:若二叉树为空,则空操作,否则①后序遍历左子树②后序遍历右子树③访问根结点后序遍历右图结果为:745289631满二叉树:一棵深度为h且有 2^h-1个结点的二叉树。

满二叉树一定为完全二叉树,但是完全二叉树不一定为满二叉树。

若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

满二叉树有如下性质:如果一颗树深度为h,最大层数为k,且深度与最大层数相同,即k=h;1、它的叶子数是:2^(h-1)2、第k层的结点数是:2^(k-1)3、总结点数是:2^k-1 (2的k次方减一)4、总节点数一定是奇数。

若设二叉树的深度为h,除第h 层外,其它各层(1~h-1) 的结点数都达到最大个数,第h 层所有的结点都连续集中在最左边,这就是完全二叉树。

1、二叉树的序遍历题目描述Description求一棵二叉树的前序遍历,中序遍历和后序遍历输入描述Input Description第一行一个整数n,表示这棵树的节点个数。

接下来n行每行2个整数L和R。

动态规划讲解大全含例题及答案

动态规划讲解大全含例题及答案

动态规划讲解大全含例题及答案动态规划讲解大全动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。

20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时,提出了著名的最优化原理(principle of optimality),把多阶段过程转化为一系列单阶段问题,逐个求解,创立了解决这类过程优化问题的新方法——动态规划。

1957年出版了他的名著Dynamic Programming,这是该领域的第一本著作。

动态规划问世以来,在经济管理、生产调度、工程技术和最优控制等方面得到了广泛的应用。

例如最短路线、库存管理、资源分配、设备更新、排序、装载等问题,用动态规划方法比用其它方法求解更为方便。

虽然动态规划主要用于求解以时间划分阶段的动态过程的优化问题,但是一些与时间无关的静态规划(如线性规划、非线性规划),只要人为地引进时间因素,把它视为多阶段决策过程,也可以用动态规划方法方便地求解。

动态规划程序设计是对解最优化问题的一种途径、一种方法,而不是一种特殊算法。

不象前面所述的那些搜索或数值计算那样,具有一个标准的数学表达式和明确清晰的解题方法。

动态规划程序设计往往是针对一种最优化问题,由于各种问题的性质不同,确定最优解的条件也互不相同,因而动态规划的设计方法对不同的问题,有各具特色的解题方法,而不存在一种万能的动态规划算法,可以解决各类最优化问题。

因此读者在学习时,除了要对基本概念和方法正确理解外,必须具体问题具体分析处理,以丰富的想象力去建立模型,用创造性的技巧去求解。

我们也可以通过对若干有代表性的问题的动态规划算法进行分析、讨论,逐渐学会并掌握这一设计方法。

基本模型多阶段决策过程的最优化问题。

在现实生活中,有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果。

动态规划-最优二叉搜索树

动态规划-最优二叉搜索树

动态规划-最优⼆叉搜索树摘要: 本章介绍了⼆叉查找树的概念及操作。

主要内容包括⼆叉查找树的性质,如何在⼆叉查找树中查找最⼤值、最⼩值和给定的值,如何找出某⼀个元素的前驱和后继,如何在⼆叉查找树中进⾏插⼊和删除操作。

在⼆叉查找树上执⾏这些基本操作的时间与树的⾼度成正⽐,⼀棵随机构造的⼆叉查找树的期望⾼度为O(lgn),从⽽基本动态集合的操作平均时间为θ(lgn)。

1、⼆叉查找树 ⼆叉查找树是按照⼆叉树结构来组织的,因此可以⽤⼆叉链表结构表⽰。

⼆叉查找树中的关键字的存储⽅式满⾜的特征是:设x为⼆叉查找树中的⼀个结点。

如果y是x的左⼦树中的⼀个结点,则key[y]≤key[x]。

如果y是x的右⼦树中的⼀个结点,则key[x]≤key[y]。

根据⼆叉查找树的特征可知,采⽤中根遍历⼀棵⼆叉查找树,可以得到树中关键字有⼩到⼤的序列。

介绍了⼆叉树概念及其遍历。

⼀棵⼆叉树查找及其中根遍历结果如下图所⽰:书中给出了⼀个定理:如果x是⼀棵包含n个结点的⼦树的根,则其中根遍历运⾏时间为θ(n)。

问题:⼆叉查找树性质与最⼩堆之间有什么区别?能否利⽤最⼩堆的性质在O(n)时间内,按序输出含有n个结点的树中的所有关键字?2、查询⼆叉查找树 ⼆叉查找树中最常见的操作是查找树中的某个关键字,除了基本的查询,还⽀持最⼤值、最⼩值、前驱和后继查询操作,书中就每种查询进⾏了详细的讲解。

(1)查找SEARCH 在⼆叉查找树中查找⼀个给定的关键字k的过程与⼆分查找很类似,根据⼆叉查找树在的关键字存放的特征,很容易得出查找过程:⾸先是关键字k与树根的关键字进⾏⽐较,如果k⼤⽐根的关键字⼤,则在根的右⼦树中查找,否则在根的左⼦树中查找,重复此过程,直到找到与遇到空结点为⽌。

例如下图所⽰的查找关键字13的过程:(查找过程每次在左右⼦树中做出选择,减少⼀半的⼯作量)书中给出了查找过程的递归和⾮递归形式的伪代码:1 TREE_SEARCH(x,k)2 if x=NULL or k=key[x]3 then return x4 if(k<key[x])5 then return TREE_SEARCH(left[x],k)6 else7 then return TREE_SEARCH(right[x],k)1 ITERATIVE_TREE_SEARCH(x,k)2 while x!=NULL and k!=key[x]3 do if k<key[x]4 then x=left[x]5 else6 then x=right[x]7 return x(2)查找最⼤关键字和最⼩关键字 根据⼆叉查找树的特征,很容易查找出最⼤和最⼩关键字。

11树型动态规划的实例分析

11树型动态规划的实例分析

• • •
••Βιβλιοθήκη ●样例求解过程:初始f(i,0)=0 f(6,1)=6, f(5,1)=max{1,6}=6, f(7,1)=2 f(4,1)=max{1,2}=2, f(1,1)=max{1,f(4,1)}=2 f(3,1)=4, f(2,1)=max{1,4}=4 f(5,2)=7 f(7,2)=max{f(5,1)+2}=8 f(4,2)=max{f(7,2),f(7,1)+1}=8 f(1,2)=max{f(4,2),f(4,1)+2}=8 f(2,2)=max{f(1,1)+1, f(3,1)+1)}=5 f(7,3)=9 f(4,3)=max{f(7,2)+1,f(7,3)}=9 f(1,3)=max{f(4,2)+1,f(4,3)}=9 f(2,3)=max{f(1,1)+f(3,1)+1,f(1,2)+1}=9 f(2,4)=max{f(1,3)+1, f(1,2)+f(3,1)+1}=max{9+1,8+4+1}=13 因此,我们设f(i,j)表示以i为根结点的二叉树分配j门课程的所获得的最大学 分,则有,
● [问题描述] ● 在大学里每个学生,为了达到一定的学分,必须从很多课 程里选择一些课程来学习,在课程里有些课程必须在某些 课程之前学习,如高等数学总是在其它课程之前学习。 ● 现在有N门功课,每门课有个学分,每门课有一门或没有 直接先修课(若课程a是课程b的先修课即只有学完了课程 a,才能学习课程b)。 ● 一个学生要从这些课程里选择M门课程学习,问他能获得 的最大学分是多少?
动态规划
● 仔细理解左右孩子的意义(如右图): 左孩子:原根结点的孩子 右孩子:原根结点的兄弟 ● 也就是说,左孩子分配选课资源时, 根结点必须要选修,而与右孩子无关。

树形数位动态规划_黄哲威

树形数位动态规划_黄哲威

花神的数论题
» 用用sum(i)表示数i二二进制表示下1的个数。 » 问sum(1)~sum(n)这n个数的乘积对
1000000007取模的结果。 » n<=10^15
» 这使得NOIp中看似没有单独讨论数位DP的必 要。
» 但事实上这种方方法还是有或多或少的细节,所以 大大家还是把数位DP看成一一类特殊的DP。初学者 一一般比比较难以一一次写对,但好好对拍就没事了了。
WINDY数
» windy定义了了一一种windy数。不不含前导零且相 邻两个数字之差至至少为2的正整数被称为 windy数。 windy想知道,在A和B之间,包括 A和B,总共有多少个windy数?将答案对 1000000007取模。
树形与数位动态规划
2019年年1月月26日日
⻩黄哲威 hzwer
北北京大大学16级计算机科学
第三节目目标
• 一一些树形dp补充
• 数位dp介绍
• 数位dp练习
NOIP2014 联合权值
» 无无向连通图 G 有 n 个点,n-1 条边。点从 1 到 n 依次编 号,编号为 i 的点的权值为 Wi,每条边的⻓长度均为 1。
» 但是这题数据范围有10^9,(sqrt(B)),这里里里取60000左右。然后预处理理出所有 F[k*S], k=1,2,...
» 这样读入入询问后,找到离B最近的一一个k*S,从F[k*S]开始暴暴力力力计算F[B]。 例例如B=60111,那么因为已经算出了了F[60000],暴暴力力力for i=60001 ... 60111 判断每个i是否是windy数即可。
• 在n个点的点权树上选两条不不相交的路路径,使
路路径上的点权和最大大
• n <= 100000

树形动态规划

树形动态规划

【核心代码】
【问题描述】
建立一个古城堡,城堡中的路形成一棵树。要在这棵树的结
点上放置最少数目的士兵,使得这些士兵能瞭望到所有的路。
一个结点上的士兵时,可以瞭望到所有与该结点相连的边。
请你编一个程序,给定一棵树,计算出需要放置最少的士兵
。 【样例输入】
0
Hale Waihona Puke 40111223
1
20
30 【样例输出】
2
3
求一棵边带权的树中的点,使得此点到树中的其他结点的最 远距离最近。
解法:从任意一点i出发的最长路径的可能形态有两种: u[i]:向上,即终点不在以i为根的子树中的最长路长度; d1[i]:向下,即终点在以i为根的子树中的最长路长度;
关键:如何计算u[i]。i点向上的路径必经过(i,prt[i]), 而prt[i]又引出了两条路径:一条是u[prt[i]];另一条是prt[i] 向下的路,该路径不能途径i点,否则会产生重复计算。
当然,x=0是一个特例,因为虚拟的根节点实际上不需要被选 修,此时背包总容积应为t。我们用分组背包进行树形DP的状态转 移。
这类题目被称为背包类树形DP,又称有树形依赖的背包问题。 在状态转移时,我们要处理的实际上就是一个分组背包问题。
【核心代码】
【问题描述】
如果一个数x的约数和y(不包括它本身)比它本身小,那么
设:f(i,0):i被父亲看时,以i为根的子树所需最少士兵; f(i,1):i被儿子看时,以i为根的子树所需最少士兵; f(i,2):在i安排警卫时,以i为根的子树所需最少士兵。
【思路点拨】 针对这三种状态,设计出状态转移方程: ①f(i,0):i被父亲看到,这时i没有安排警卫,i的儿子
要么安排警卫,要么被它的后代看到,则:

动态规划算法入门,需要搞懂这5个问题

动态规划算法入门,需要搞懂这5个问题

动态规划算法入门,需要搞懂这5个问题不久前不少人留言说要介绍介绍动态规划,今天我们就来介绍介绍什么是动态规划。

动态规划算法是现实中非常的一个算法。

之前我们做过一个判断送餐的骑手能否在规定时间内送完手头的外卖,就用了这个算法。

(当然,算出来的只是一个理论的结果,但可以防止骑手一下子接太多单,最后造成用户投诉)。

后面如果有机会会介绍一下这个问题的实现。

这个问题挺有趣的。

可以抛出来给大家思考一下。

现在有一个骑手,知道他的坐标,然后有一些外卖订单,我们知道每个订单的位置还有预计送达时间。

我们能否快速判断这个骑手能否在规定时间内把这批订单送完。

相比于直接搜索,动态规划往往更加高效。

现在我们通过5个问题,来认识什么是动态规划。

第一,什么是动态规划?动态规划(英语:Dynamic programming,简称DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。

重点在后半句,把问题分解成简单子问题进行解决。

与之类似的有另外一个算法,分治。

他俩最大的区别在于子问题之间是否相关联。

第二,动态规划的思想?动态规划的思想很简单,就是分解问题求解,然后再合并子问题的解。

第三,哪些问题可以用动态规划来解决?接下来的内容可能比较难以理解,我们通过一个经典的面试题,然后接着讲。

最长上升子序列(LIS),有一串序列,要求找出它的一串子序列,这串子序列可以不连续,但必须满足它是严格的单调递増的且为最长的。

把这个长度输出。

示例:1 7 3 5 9 48 结果为4。

1.最优子结构性质。

如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。

上面的题目。

如果我们假设f[3]表示以a[3]结尾的最长上升子序列,那么转移到它的子问题一定要是最优的。

也就是从f[2]也要求是最优的。

2.无后效性。

即子问题的解一旦确定,就不再改变,不受在这之后、包含它的更大的问题的求解决策影响。

树型动态规划

树型动态规划

树型动态规划树型动态规划⼀、基本概念树型动态规划,顾名思义,就是在“树”的数据结构上做动态规划,通过有限次地遍历树,记录相关信息,以求解问题。

通常,动态规划都是线性的或者建⽴在图上的,分为逆推和顺推。

①叶->根,即根的⼦节点传递有⽤的消息给根,之后由根得出最优解的过程。

这种⽅式DP的题⽬应⽤⽐较多。

②根->叶,即需要取所有点作为⼀次根节点进⾏求值,此时⽗节点得到了整棵树的信息,只需要去除这个⼉⼦的DP值的影响,然后再转移给这个⼉⼦,这样就能达到根->叶的顺序动态规划的顺序:⼀般按照后序遍历的顺序,⼏处理完⼉⼦再处理当前结点,才符合树的⼦结构的性质。

实现⽅式:树型DP是通过记忆化搜索实现的,因此采⽤的是递归⽅式,时间复杂度:树型动态规划的时间复杂度基本上是O(n);若有附加维m,则是O(n * m)⼆、经典问题1.树的重⼼对于⼀颗n个节点的⽆根树,找到⼀个点,使得把树变成以该点为根的有根树时,最⼤⼦树的节点最⼩,换句话说,删除这个点后最⼤连通块的节点数最⼩,那么这个点就是树的重⼼。

解法:任选⼀个节点作为根进⾏dfs然后根据定义动态规划寻找树的重⼼。

2.树的最长路径(最远点对)给定⼀颗n个结点的边带权树找到⼀条最长的路径,换句话说,要找到两个点,使得他们的距离最远,他们之间的路径就是树的最长路径解法:⽤d1[i],d2[i]记录以i为根的⼦树中到叶节点的最⼤值和次⼤值,j是i的⼉⼦①d1[j] + dis[i][j] > d1[i] 则d2[i] = d1[i],d1[i] = d1[j] + dis[i][j]②d1[j] + dis[i][j] > d2[i] 则d2[i] = d1[j] + dis[i][j]3.树的中⼼问题给出⼀颗带权的树,求树中的点,使得此点到树中的其他节点的最远距离最近分析:从任意⼀个点i出发的最长路径的可能形态有两种。

①从i点出发向上,即终点不在以i为根的⼦树中的最长路径长度为u[i]②从i点出发向下,即终点在以i为根的⼦树中的最长路径长度为d1[i]注意:第⼀种⾥⾯不要重复经过i点分别⽤c1[i]和c2[i]记录d1[i]和d2[i]是从哪个⼦树更新来的。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Begin for i:=1 to n do if father[i]=v then begin dfs(i); dp[v] end;
End;
fun(dp[i])
分析单纯 的dfs
这种朴素的dfs很好理解,但是,在我们计算 过程中,肯定出现了大量的重复。因此,我们 要在计算的时候 “只算一次”。

end;

end;

end;
主程序

begin

readln(n,q);

for i:=1 to n do for j:=1 to n do map[i,j]:=-1;

for i:=1 to n-1 do

begin

readln(a,b,c);

map[a,b]:=c;map[b,a]:=c;
对于每个节点的状态,与且只与其所属的孩子 节点有关(一般为2个,如果不是2个,需要转 换),也就是说每个节点的状态与其父节点无 关。
状态可以用简单的数组来表示。 如果用dfs会有大量的重复计算。
二叉苹果树的解决
此问题可以转化为: 对于一个二叉树,除了根节点外,每个节点都
有相应的一个权值,在此基础上,求保留多少 个点使得其仍然满足树的性质(树的性质有什 么?)且权值最大,当然,根节点是必须保留 的。
begin

ch[v,1]:=i;

num[i]:=map[v,i];

map[v,i]:=-1;map[i,v]:=-1;

maketree(i);

break;
end;
for i:=1 to n do
if map[v,i]>=0 then
begin

ch[v,2]:=i;

num[i]:=map[v,i];
如果是多叉怎么办?
选课(如果看不清,看下一页)
在大学里每个学生,为了达到一定的学分,必须从很多课程里 选择一些课程来学习,在课程里有些课程必须在某些课程之前 学习,如高等数学总是在其它课程之前学习。现在有N门功课, 每门课有个学分,每门课有一门或没有直接先修课(若课程a是 课程b的先修课即只有学完了课程a,才能学习课程b)。一个 学生要从这些课程里选择M门课程学习,问他能获得的最大学 分是多少?
树形动态规划
什么是树型动态规划
顾名思义,树型动态规划就是在“树”的数据结构上 的动态规划,平时作的动态规划都是线性的或者是建 立在图上的,线性的动态规划有二种方向既向前和向 后,相应的线性的动态规划有二种方法既顺推与逆推, 而树型动态规划是建立在树上的,所以也相应的有二 个方向: (1)根—>叶:不过这种动态规划在实际的问题 中运用的不多,也没有比较明显的例题,所以不在今 天讨论的范围之内。 (2)叶->根:既根的子节点传递有用的信息给 根,完后根得出最优解的过程。这类的习题比较的多, 下面就介绍一些这类题目和它们的一般解法。
动态规划设定
根据前边动态规划的经验,状态函数是第一要 务,那么状态应该怎么表示呢?
仿照线性的,我们设 ch[v,1] 和 ch[v,2]分别表 示 v节点的左孩子和右孩子。
f[i,j]表示 以第i个节点为根的子树保留j个节点 的最大权和。
那么转移方程就是
F[I,j]=max(f[ch[I,1],k)+f[ch[I,2],j-k-1]) (0<=k<=j-1)(想一下,为什么是 j-1)
输出格式
一个数,最多能留住的苹果的数量。(剪枝时,千万不要连根拔起哦)
样例输入
52 131 1 4 10 2 3 20 3 5 20
样例输出
21
思考
这道题能不能还像上道题一样用线性dp 如果用dfs呢? 还有什么方法?
应用树形动态规划的前提
整个图是一个树形结构或者可以转化为树形结 构。
输入样例: 74 22 01 04 21 71 76 22 输出样例: 13
我们用函数f(i,j)表示以第i个节点为父节点,取j 个子节点的最佳代价,则:
j jch1n jch1nch2n ( jch1nch2n ch(i1)n f (ch1, ch1n) f (ch2, ch2n)
如何实现
树形结构本身就是递归结构。所以,我们用的 更多的递归的形式来构造树。
而在状态转移的时候,我们一般都是叶子节点 出发,根节点为最终结果。这样,如果用记忆 化搜索的方式,动态规划的过程和构造树的方 向基本一致,有时候还可以合二为一。
先写出dfs框架
Procedure dfs(v); var i:longint;
此题是批着 树形 外观的 非树形动态规划 题。而真正的树形动态规划是在树上做动 态规划。
苹果二叉树 (apple)
题目描述
有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个 儿子的结点)这棵树共有N个结点(叶子点或者树枝分叉点),编号 为1-N,树根编号一定是1。我们用一根树枝两端连接的结点的编号来描 述一根树枝的位置。
【输出样例】 145 31245
此题要求在求最优值的基础上把树的结构给构 造出来,所以,从本质上,此题为区间型的一 维线性动态规划。
如果用数组value[i,j]表示从节点i到节点j所组成 的二叉树的最大加分,则动态方程可以表示如 下:
value[i,j]=max{value[i,i]+value[i+1,j],
现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。 给定需要保留的树枝数量,求出最多能留住多少苹果。
输入格式
第1行2个数,N和Q(1<=Q<= N,1<N<=100)。 N表示树的结点数,Q表示要保留的树枝数量。接下来N-1行描述树枝 的信息。 每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上 苹果的数量。 每根树枝上的苹果不超过30000个。

else begin

dp[v,l]:=0;

for i:=0 to l-1 do

begin

if dp[ch[v,1],i]=0 then dfs(ch[v,1],i);

if dp[ch[v,2],l-i-1]=0 then dfs(ch[v,2],l-i-1);

dp[v,l]:=max(dp[v,l],dp[ch[v,1],i]+dp[ch[v,2],l-i-1]+num[v]);
【输入格式】 第1行:一个整数n(n<30),为节点个数。 第2行:n个用空格隔开的整数,为每个节点的分数(分数 <100)。
【输出格式】 第1行:一个整数,为最高加分(结果不会超过 4,000,000,000)。 第2行:n个用空格隔开的整数,为该树的前序遍历。
【输入样例】 5 5 7 1 2 10
我们用函数f(I,j)表示以第i个 节点为父节点,取j个子节点的 最佳代价,这和前一个函数表 示的意义是一致的,但方程有 了很大的改变:
f
(i,
j)

max{ff
(leftc,k ) f (rightc, j)
} (rightc, jk1)s[i]
1<=i<=m,1<=j<=n,0<=k<j
f (i, j) max

ch1n1 ch2n1 ch3n1
chin
f (chi, chin))
可是如此规划,其效率与搜索毫无差别,虽然我们 可以再次用动态规划来使它的复杂度变为平方级, 但显得过于麻烦。
转变为二叉树。如果两节点a,b 同为兄弟,则将b设为a的右节 点;如果节点b是节点a的儿子, 则将节点b设为节点a的左节点。 树改造完成后如图3。
value[k,k]+value[I,k-1]*value[k+1,j],
value[j,j]+value[i,j-1]} (i<k<j)
输出因为要输出树的结构,所以,还要在动态 规划的过程中,把每个区间的根给求出来。
设 root[I,j] 构了。
这个方程的时间复杂度最大为n3,十分优秀了。
在具体实现这道题时,我们可以自顶而下,用 递归进行树的遍历求解
程序实现
读入数据时把二叉树建好:第一个孩子作为父节点的左 子树,其它孩子作为第一个孩子的右子树。
F(x,y):表示节点x取y门课得最高学分,则 F(x,y)=max(f(x.l,k-1)+x.v+f(x.r,y-k))

map[v,i]:=-1;map[i,v]:=-1;

maketree(i);

break;
end;
end;
主要过程

procedure dfs(v,l:longint);

var

i:longint;

begin

if (l=0) then dp[v,l]:=0

else if (ch[v,1]=0)and(ch[v,2]=0) then dp[v,l]:=num[v]
k=0,1,..y f(x.l,k-1)+x.v(课程x的学分) :表示选了课程x,左孩子
选k-1门课,共k门课。 f (x.r,y-k)表示右孩子只能选y-k门课。 标程中节点-1表示空节点,0是根节点,1—n是n门
可选课程的节点
皇宫看守(guard)
太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫。皇宫 以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状;某些 宫殿间可以互相望见。大内保卫森严,三步一岗,五步一哨,每 个宫殿都要有人全天候看守,在不同的宫殿安排看守所需的费用 不同。可是陆小凤手上的经费不足,无论如何也没法在每个宫殿 都安置留守侍卫。编程任务:帮助陆小凤布置侍卫,在看守全部 宫殿的前提下,使得花费的经费最少。
相关文档
最新文档