动态规划专题(六):树型动态规划
动态规划
多阶段决策问题中,各个阶段采取的决策,一般来说是与时间有关的,决策依赖于当前状态,又随即引起状 态的转移,一个决策序列就是在变化的状态中产生出来的,故有“动态”的含义,称这种解决多阶段决策最优化 问题的方法为动态规划方法 。
任何思想方法都有一定的局限性,超出了特定条件,它就失去了作用。同样,动态规划也并不是万能的。适 用动态规划的问题必须满足最优化原理和无后效性 。
动态规划
运筹学的分支
01 原理
03 局限性
目录
02 分类
动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程。20世纪50年 代初,美国数学家贝尔曼(R.Bellman)等人在研究多阶段决策过程的优化问题时,提出了著名的最优化原理, 从而创立了动态规划。动态规划的应用极其广泛,包括工程技术、经济、工业生产、军事以及自动化控制等领域, 并在背包问题、生产经营问题、资金管理问题、资源分配问题、最短路径问题和复杂系统可靠性问题等中取得了 显著的效果 。
最优化原理可这样阐述:一个最优化策略具有这样的性质,不论过去状态和决策如何,对前面的决策所形成 的状态而言,余下的诸决策必须构成最优策略。简而言之,一个最优化策略的子策略总是最优的。一个问题满足 最优化原理又称其具有最优子结构性质 。
将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态无法直接影响它未来 的决策,而只能通过当前的这个状态。换句话说,每个状态都是过去历史的一个完整总结。这就是无后向性,又 称为无后效性 。
状态:状态表示每个阶段开始面临的自然状况或客观条件,它不以人们的主观意志为转移,也称为不可控因 素。在上面的例子中状态就是某阶段的出发位置,它既是该阶段某路的起点,同时又是前一阶段某支路的终点 。
第6章动态规划
第6章 动态规划动态规划(Dynamic Programming )是解决多阶段决策过程最优化的一种有用的数学方法。
它是由美国学者Richard .Bellman 在1951年提出的,1957年他的专著《动态规划》一书问世,标志着运筹学的一个重要分支-动态规划的诞生.动态规划也是一种将多变量问题转化为单变量问题的一种方法。
在动态规划中,把困难的多阶段决策问题变换成一系列相互联系的比较容易的单阶段问题一个个地求解。
动态规划是考察解决问题的一种途径 ,而不是一种特殊的算法,不像线性规划那样有统一的数学模型和算法(如单纯形法).事实上,在运用其解决问题的过程中还需要运用其它的优化算法。
因此,动态规划不像其它方法局限于解决某一类问题,它可以解决各类多阶段决策问题。
动态规划在工程技术、经济管理等社会各个领域都有着广泛的应用,并且获得了显著的效果。
在经济管理方面,动态规划可以用来解决最优路径问题、资源分配问题、生产调度问题、库存管理问题、排序问题、设备更新问题以及生产过程最优控制问题等,是经济管理中一种重要的决策技术。
许多规划问题用动态规划的方法来处理,常比线性规划或非线性规划更有效。
特别是对于离散的问题,由于解析数学无法发挥作用,动态规划便成为了一种非常有用的工具。
动态规划可以按照决策过程的演变是否确定分为确定性动态规划和随机性动态规划;也可以按照决策变量的取值是否连续分为连续性动态规划和离散性动态规划。
本教材主要介绍动态规划的基本概念、理论和方法,并通过典型的案例说明这些理论和方法的应用。
6.1动态规划的基本理论6.1.1多阶段决策过程的数学描述有这样一类活动过程,其整个过程可分为若干相互联系的阶段,每一阶段都要作出相应的决策,以使整个过程达到最佳的活动效果。
任何一个阶段(stage ,即决策点)都是由输入(input )、决策(decision )、状态转移律(transformation function )和输出(output )构成的,如图6-1(a )所示.其中输入和输出也称为状态(state ),输入称为输入状态,输出称为输出状态。
树型动态规划(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。
第6章-动态规划
求解过程
由最后一个阶段的优化开始,按逆向顺序逐步 向前一阶段扩展,并将后一阶段的优化结果带 到扩展后的阶段中去,以此逐步向前推进,直 至得到全过程的优化结果。
f1
(
A)
min
dd11
( (
A, A,
B1) B2 )
ff22((BB12))
min
4 9
9 11
13
d1( A, B3) f2 (B3)
5 13
其最短路线是A→ B1→C2 →D2 →E ,相应的决 策变量是u1(A)=B1
因此,最优策略序列是:
u1(A) =B1, u2(B1)=C2, u3(C2)=D2, u4(D2)=E
5 8 C2 4 6 4
4 C3 2
C3
D1 4 2 6
D2 9 7
D3 5
D4
E1 1 F
E2 2
E5
F
动态规划的逆序解法与顺序解法
逆序(递推)解法:即由最后一段到第一段逐步 求出各点到终点的最短路线,最后求出A点到E点 的最短路线。运用逆序递推方法的好处是可以始 终盯住目标,不致脱离最终目标。 顺序解法:其寻优方向与过程的行进方向相同, 求解时是从第一段开始计算逐段向后推进,计算 后一阶段时要用到前一段求优的结果,最后一段 的计算结果就是全过程的最优结果。
B1
A
4+9=13
d(u1)+f2
B2
B3
f1(s1) u1*
树形动态规划
树形动态规划动态规划: 问题可以分解成若⼲相互联系的阶段,在每⼀个阶段都要做出决策,全部过程的决策是⼀个决策序列。
要使整个活动的总体效果达到最优的问题,称为多阶段决策问题。
动态规划就是解决多阶段决策最优化问题的⼀种思想⽅法。
阶段: 将所给问题的过程,按时间或空间(树归中是空间,即层数)特征分解成若⼲相互联系的阶段,以便按次序去求每阶段的解。
状态: 各阶段开始时的客观条件叫做状态。
决策: 当各段的状态取定以后,就可以做出不同的决定,从⽽确定下⼀阶段的状态,这种决定称为决策。
(即孩⼦节点和⽗亲节点的关系)策略: 由开始到终点的全过程中,由每段决策组成的决策序列称为全过程策略,简称策略。
状态转移⽅程: 前⼀阶段的终点就是后⼀阶段的起点,前⼀阶段的决策选择导出了后⼀阶段的状态,这种关系描述了由k阶段到k+1阶段(在树中是孩⼦节点和⽗亲节点)状态的演变规律,称为状态转移⽅程。
⽬标函数与最优化概念: ⽬标函数是衡量多阶段决策过程优劣的准则。
最优化概念是在⼀定条件下找到⼀个途径,经过按题⽬具体性质所确定的运算以后,使全过程的总效益达到最优。
树的特点与性质:1、有n个点,n-1条边的⽆向图,任意两顶点间可达2、⽆向图中任意两个点间有且只有⼀条路3、⼀个点⾄多有⼀个前趋,但可以有多个后继4、⽆向图中没有环;拿到⼀道树规题,我们有以下3个步骤需要执⾏:1. 判断是否是⼀道树规题:即判断数据结构是否是⼀棵树,然后是否符合动态规划的要求。
如果是,那么执⾏以下步骤,如果不是,那么换台。
2. 建树:通过数据量和题⽬要求,选择合适的树的存储⽅式。
如果节点数⼩于5000,那么我们可以⽤邻接矩阵存储,如果更⼤可以⽤邻接表来存储(注意边要开到2*n,因为是双向的。
这是⾎与泪的教训)。
如果是⼆叉树或者是需要多叉转⼆叉,那么我们可以⽤两个⼀维数组brother[],child[]来存储(这⼀点下⾯会仔细数的)。
3. 写出树规⽅程:通过观察孩⼦和⽗亲之间的关系建⽴⽅程。
树形动态规划
【核心代码】
【问题描述】
建立一个古城堡,城堡中的路形成一棵树。要在这棵树的结
点上放置最少数目的士兵,使得这些士兵能瞭望到所有的路。
一个结点上的士兵时,可以瞭望到所有与该结点相连的边。
请你编一个程序,给定一棵树,计算出需要放置最少的士兵
。 【样例输入】
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的儿子
要么安排警卫,要么被它的后代看到,则:
树形动态规划
总结
这堂课讲的内容只能算是基础,题目中 树的条件直接给出,动归的指向性也很 明显。有些难度较高的树型动态规划题, 在题目中会把“树”的条件隐藏,还有 些题目需要经过适当转化才能找到最优 子结构。选手们只有平时多做题,多思 考,能力提升了,才能应对各种变化。
树型动态规划
JSOI2010冬令营
引言
树是一种特殊的图,可以描述比较复杂的关系,而大 多数动归都是在一维二维这种规则的背景下的,再加 上树递归定义的性质,可以说是一种非常合适的动归 框架,树型动态规划就成为动规中重要的一类题型。
因为树可以描述比较复杂的关系,这对选手分析问题 的能力有较高的要求,在寻找最优子结构、组织状态 时往往需要创造性思维,而且树型动态规划对数学要 求不高,一般不涉及单调性优化,所以竞赛中往往将 它作为侧重考察选手分析思考能力的题出现。
例二、问题分析
三种情况
例二、问题分析
|XY|+|YZ|
|XY|+|YX|+|XZ|
例二、问题分析
例二、问题分析
现在只要考虑这一种情况 要满足|Xa|+|aY|≦ |Xa|+|aZ|
|Xa|+2|aY|+|aZ|最大
例二、问题分析
现在我们考虑分叉点a
很明显,要使目标值最大,XYZ必是离a最 远的三点,且在以a为根的三棵不同子树中。 Y就是三点中离a第二远的点。 显然,三个点要么位于以a为根的子树中, 要么位于以a为根的子树外。
例一、问题描述
给定一棵树,树的每个节点有一个权值, 要求从中选出一些不相邻的点,使选出 的节点权值和最大。
例一、确定状态
对于大多数树型动态规划问题,都是用 一棵子树的根节点编号来作为代表这棵 子树的第一维状态,然后再根据需要加 维。
动态规划基础、进阶与优化
山东师大附中陈键飞前言自古以来就是NOIP的重要考察内容,在联赛中占的分量大。
对选手能力有一定要求,需要能够熟练地建立动态规划模型。
需要大量做题,初学者不易掌握其思想。
目录基础:基本概念背包问题——一类典型应用 进阶:更多的问题树形DP状态压缩优化:减少状态数目减少状态转移(决策)时间基本概念最长上升子序列状态:f[i]能完全地表示出问题某个或某些本质相同的形态决策:f[i]=min(f[j]+1)状态由哪个状态转移得到阶段:每个i前面的阶段决定后面的阶段,后面的阶段由前面的状态转移得到基本概念石子合并状态f[i,j]决策f[i,j]=min(f[i,k]+f[k+1,j])+w[i,j] 阶段j-i (区间大小)基本概念无后效性后面阶段的状态只受前面阶段的状态的影响 对于任意两个状态,只能单向的进行转移基本概念拓扑图(有向无环图)无后效性f[i]=min(f[j])+1基本概念 非拓扑图(可能有环) 有后效性a →b →c ?b →c →a ?a bc 51111基本概念最优子问题问题最优,只需子问题最优,与到达子问题的路径无关3 5 24 6f(5)最优,只需f(4)最优,与f(4)是怎么到达的无关与路线具体是3 4 6还是2 4 6无关基本概念最优子问题输出1~n中∑(A(i,p[i]))最大的排列f(i)表示用1~n组成的长度为i的序列? 与到达子问题的路径有关!1 4 3 →6 ?4 2 3 →6 ?基本概念无后效性、最优子问题是否能满足与状态的表示,状态的转移,阶段的划分有关背包问题——一类典型应用 给定n个货币,面值各不相同,问能否凑出m元钱f[i,j]表示前i个货币能否凑出j元f[i,j] = f[i-1,j] (不选j)or f[i-1,j-w[i]](选j)背包问题——一类典型应用 给定n种货币,每种无限多个,面值各不相同,问能否凑出m元钱f[i,j]表示前i种货币能否凑出j元f[i,j]=f[i-1,j] or f[i,j-w[i]]背包问题——一类典型应用 给定n种货币,第i种有A i个,面值W i,问能否凑出m 元钱将每种货币i拆成A i个价值为W i的货币O(m∑A i)将每种货币i拆成价值为W i,2W i,4W i,8W i……的货币O(m∑log A i)单调队列O(mn) ,暂时跳过背包问题——一类典型应用 给定n种货币分为k组,每组只能选一个,问能否凑出m元f[i,j,k]表示用前1~i-1组和第i组的前j个能否凑出k元。
北大poj题目分类
初期:一.基本算法:(1)枚举. (poj1753,poj2965)(2)贪心(poj1328,poj2109,poj2586)(3)递归和分治法.(4)递推.(5)构造法.(poj3295)(6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法:(1)图的深度优先遍历和广度优先遍历.(2)最短路径算法(dijkstra,bellman-ford,floyd,heap+dijkstra)(poj1860,poj3259,poj1062,poj2253,poj1125,poj2240)(3)最小生成树算法(prim,kruskal)(poj1789,poj2485,poj1258,poj3026)(4)拓扑排序(poj1094)(5)二分图的最大匹配(匈牙利算法) (poj3041,poj3020)(6)最大流的增广路算法(KM算法). (poj1459,poj3436)三.数据结构.(1)串(poj1035,poj3080,poj1936)(2)排序(快排、归并排(与逆序数有关)、堆排) (poj2388,poj2299)(3)简单并查集的应用.(4)哈希表和二分查找等高效查找法(数的Hash,串的Hash)(poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503)(5)哈夫曼树(poj3253)(6)堆(7)trie树(静态建树、动态建树) (poj2513)四.简单搜索(1)深度优先搜索(poj2488,poj3083,poj3009,poj1321,poj2251)(2)广度优先搜索(poj3278,poj1426,poj3126,poj3087.poj3414)(3)简单搜索技巧和剪枝(poj2531,poj1416,poj2676,1129)五.动态规划(1)背包问题. (poj1837,poj1276)(2)型如下表的简单DP(可参考lrj的书page149):1.E[j]=opt{D+w(i,j)} (poj3267,poj1836,poj1260,poj2533)2.E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最长公共子序列)(poj3176,poj1080,poj1159)3.C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最优二分检索树问题)六.数学(1)组合数学:1.加法原理和乘法原理.2.排列组合.3.递推关系.(POJ3252,poj1850,poj1019,poj1942)(2)数论.1.素数与整除问题2.进制位.3.同余模运算.(poj2635, poj3292,poj1845,poj2115)(3)计算方法.1.二分法求解单调函数相关知识.(poj3273,poj3258,poj1905,poj3122)七.计算几何学.(1)几何公式.(2)叉积和点积的运用(如线段相交的判定,点到线段的距离等). (poj2031,poj1039)(3)多边型的简单算法(求面积)和相关判定(点在多边型内,多边型是否相交)(poj1408,poj1584)(4)凸包. (poj2187,poj1113)中级:一.基本算法:(1)C++的标准模版库的应用. (poj3096,poj3007)(2)较为复杂的模拟题的训练(poj3393,poj1472,poj3371,poj1027,poj2706)二.图算法:(1)差分约束系统的建立和求解. (poj1201,poj2983)(2)最小费用最大流(poj2516,poj2516,poj2195)(3)双连通分量(poj2942)(4)强连通分支及其缩点.(poj2186)(5)图的割边和割点(poj3352)(6)最小割模型、网络流规约(poj3308, )三.数据结构.(1)线段树. (poj2528,poj2828,poj2777,poj2886,poj2750)(2)静态二叉检索树. (poj2482,poj2352)(3)树状树组(poj1195,poj3321)(4)RMQ. (poj3264,poj3368)(5)并查集的高级应用. (poj1703,2492)(6)KMP算法. (poj1961,poj2406)四.搜索(1)最优化剪枝和可行性剪枝(2)搜索的技巧和优化(poj3411,poj1724)(3)记忆化搜索(poj3373,poj1691)五.动态规划(1)较为复杂的动态规划(如动态规划解特别的施行商问题等)(poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034)(2)记录状态的动态规划. (POJ3254,poj2411,poj1185)(3)树型动态规划(poj2057,poj1947,poj2486,poj3140)六.数学(1)组合数学:1.容斥原理.2.抽屉原理.3.置换群与Polya定理(poj1286,poj2409,poj3270,poj1026).4.递推关系和母函数.(2)数学.1.高斯消元法(poj2947,poj1487, poj2065,poj1166,poj1222)2.概率问题. (poj3071,poj3440)3.GCD、扩展的欧几里德(中国剩余定理) (poj3101)(3)计算方法.1.0/1分数规划. (poj2976)2.三分法求解单峰(单谷)的极值.3.矩阵法(poj3150,poj3422,poj3070)4.迭代逼近(poj3301)(4)随机化算法(poj3318,poj2454)(5)杂题.(poj1870,poj3296,poj3286,poj1095)七.计算几何学.(1)坐标离散化.(2)扫描线算法(例如求矩形的面积和周长并,常和线段树或堆一起使用).(poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)(3)多边形的内核(半平面交)(poj3130,poj3335)(4)几何工具的综合应用.(poj1819,poj1066,poj2043,poj3227,poj2165,poj3429)高级:一.基本算法要求:(1)代码快速写成,精简但不失风格(poj2525,poj1684,poj1421,poj1048,poj2050,poj3306)(2)保证正确性和高效性. poj3434二.图算法:(1)度限制最小生成树和第K最短路. (poj1639)(2)最短路,最小生成树,二分图,最大流问题的相关理论(主要是模型建立和求解)(poj3155, poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446(3)最优比率生成树. (poj2728)(4)最小树形图(poj3164)(5)次小生成树.(6)无向图、有向图的最小环三.数据结构.(1)trie图的建立和应用. (poj2778)(2)LCA和RMQ问题(LCA(最近公共祖先问题) 有离线算法(并查集+dfs) 和在线算法(RMQ+dfs)).(poj1330)(3)双端队列和它的应用(维护一个单调的队列,常常在动态规划中起到优化状态转移的目的). (poj2823)(4)左偏树(可合并堆).(5)后缀树(非常有用的数据结构,也是赛区考题的热点).(poj3415,poj3294)四.搜索(1)较麻烦的搜索题目训练(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426)(2)广搜的状态优化:利用M进制数存储状态、转化为串用hash表判重、按位压缩存储状态、双向广搜、A*算法. (poj1768,poj1184,poj1872,poj1324,poj2046,poj1482)(3)深搜的优化:尽量用位运算、一定要加剪枝、函数参数尽可能少、层数不易过大、可以考虑双向搜索或者是轮换搜索、IDA*算法. (poj3131,poj2870,poj2286)五.动态规划(1)需要用数据结构优化的动态规划.(poj2754,poj3378,poj3017)(2)四边形不等式理论.(3)较难的状态DP(poj3133)六.数学(1)组合数学.1.MoBius反演(poj2888,poj2154)2.偏序关系理论.(2)博奕论.1.极大极小过程(poj3317,poj1085)2.Nim问题.七.计算几何学.(1)半平面求交(poj3384,poj2540)(2)可视图的建立(poj2966)(3)点集最小圆覆盖.(4)对踵点(poj2079)八.综合题.(poj3109,poj1478,poj1462,poj2729,poj2048,poj3336,poj3315,poj2148,poj1263)以及补充Dp状态设计与方程总结1.不完全状态记录<1>青蛙过河问题<2>利用区间dp2.背包类问题<1> 0-1背包,经典问题<2>无限背包,经典问题<3>判定性背包问题<4>带附属关系的背包问题<5> + -1背包问题<6>双背包求最优值<7>构造三角形问题<8>带上下界限制的背包问题(012背包)3.线性的动态规划问题<1>积木游戏问题<2>决斗(判定性问题)<3>圆的最大多边形问题<4>统计单词个数问题<5>棋盘分割<6>日程安排问题<7>最小逼近问题(求出两数之比最接近某数/两数之和等于某数等等)<8>方块消除游戏(某区间可以连续消去求最大效益)<9>资源分配问题<10>数字三角形问题<11>漂亮的打印<12>邮局问题与构造答案<13>最高积木问题<14>两段连续和最大<15>2次幂和问题<16>N个数的最大M段子段和<17>交叉最大数问题4.判定性问题的dp(如判定整除、判定可达性等)<1>模K问题的dp<2>特殊的模K问题,求最大(最小)模K的数<3>变换数问题5.单调性优化的动态规划<1>1-SUM问题<2>2-SUM问题<3>序列划分问题(单调队列优化)6.剖分问题(多边形剖分/石子合并/圆的剖分/乘积最大)<1>凸多边形的三角剖分问题<2>乘积最大问题<3>多边形游戏(多边形边上是操作符,顶点有权值)<4>石子合并(N^3/N^2/NLogN各种优化)7.贪心的动态规划<1>最优装载问题<2>部分背包问题<3>乘船问题<4>贪心策略<5>双机调度问题Johnson算法8.状态dp<1>牛仔射击问题(博弈类)<2>哈密顿路径的状态dp<3>两支点天平平衡问题<4>一个有向图的最接近二部图9.树型dp<1>完美服务器问题(每个节点有3种状态)<2>小胖守皇宫问题<3>网络收费问题<4>树中漫游问题<5>树上的博弈<6>树的最大独立集问题<7>树的最大平衡值问题<8>构造树的最小环。
树型动态规划
树型动态规划树型动态规划⼀、基本概念树型动态规划,顾名思义,就是在“树”的数据结构上做动态规划,通过有限次地遍历树,记录相关信息,以求解问题。
通常,动态规划都是线性的或者建⽴在图上的,分为逆推和顺推。
①叶->根,即根的⼦节点传递有⽤的消息给根,之后由根得出最优解的过程。
这种⽅式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]是从哪个⼦树更新来的。
信息学奥赛——树型动态规划的实例分析
信息学奥赛——树型动态规划的实例分析树型动态规划(Tree Dynamic Programming)是信息学奥赛中常用的一种算法思想,在解决一些与树相关的问题时非常有效。
本文将通过一个具体的实例对树型动态规划进行详细分析。
假设有一棵有根树,每个节点上都有一个非负整数权值,并且每个节点下都可能有若干个子节点。
现在要求选择一些节点,使得选中的节点的权值之和尽可能大,但是不能选择相邻的节点。
我们需要设计一个算法来解决这个问题。
首先,我们可以观察到如果一个节点被选中,那么它的子节点就不能被选中。
于是,我们可以定义一个动态规划的状态dp[i]表示以节点i为根的子树中选择节点的最大权值之和。
对于根节点,我们有两种情况:1. 根节点i被选择,那么它的子节点就不能被选择。
所以dp[i] = sum(dp[j]),其中j表示i的所有子节点。
2. 根节点i不被选择,那么它的所有子节点都可以被选择。
所以dp[i] = sum(max(dp[j], dp[k])),其中j和k分别表示i的所有孩子节点的子节点。
通过对根节点的两种状态的分析,我们可以得到一个递推关系:dp[i] = max(sum(dp[j]), sum(max(dp[k], dp[l]))),其中j表示i的所有子节点,k和l分别表示i的所有孩子节点的子节点。
接下来,我们需要设计一个合适的递归算法来计算dp[i]。
我们可以使用深度优先(DFS)的方式来处理每个节点,实现递归的过程。
具体的伪代码如下:```DFS(i):visit[i] = truefor j in i的所有子节点:if visit[j] == false:DFS(j)dp[i] += dp[j]for k in i的所有孩子节点:for l in k的所有子节点:dp[i] += max(dp[k], dp[l])```最后,我们只需要调用DFS函数以根节点为参数,可以得到整棵树的最优解。
树形动态规划讲解
一个数,最多能留住的苹果的数量。(剪枝时,千万不要连根拔起哦)
样例输入
52 131 1 4 10 2 3 20 3 5 20
样例输出
21
思考
这道题能不能还像上道题一样用线性dp 如果用dfs呢? 还有什么方法?
应用树形动态规划的前提
整个图是一个树形结构或者可以转化为树形结 构。
Begin for i:=1 to n do if father[i]=v then begin dfs(i); dp[v] end;
End;
fun(dp[i])
分析单纯 的dfs
这种朴素的dfs很好理解,但是,在我们计算 过程中,肯定出现了大量的重复。因此,我们 要在计算的时候 “只算一次”。
输入样例: 74 22 01 04 21 71 76 22 输出样例: 13
我们用函数f(i,j)表示以第i个节点为父节点,取j 个子节点的最佳代价,则:
j jch1n jch1 ch1n) f (ch2, ch2n)
end;
maketree(1);
dfs(1,q+1);
writeln(dp[1,q+1]);
end.
本道题就是一道最基本的树形动态规划题。一 般树形动态规划题目分为两个步骤
(1) maketree,
(2) treedp
在树的存储结构上,我们一般选的都是二叉树, 因为二叉树可以用静态数组来存储,并且状态 转移也很好写。
这个方程的时间复杂度最大为n3,十分优秀了。
在具体实现这道题时,我们可以自顶而下,用 递归进行树的遍历求解
《树型动态规划》课件
要点二
详细描述
通过动态规划的方式,定义状态转移方程,根据当前状态 和下一个状态的关系,逐步计算出最长公共子序列的长度 。
区间dp问题的实例分析
总结词
求解区间dp问题的最优解
详细描述
将区间dp问题转化为子区间dp问题,通过 动态规划的方式,定义状态转移方程,逐步 计算出每个子区间的最优解,最终得到整个
状态压缩
通过将多个状态合并为一个状态,减少动态规划的状态数,提高 算法效率。
自底向上计算
从叶子节点开始计算,逐步向根节点推进,直到解决问题。
02
树型动态规移方程是树型动态规划的核心,它描述了从当前状态 转移到下一状态的过程。通过状态转移方程,我们可以计算 出每个节点的最小成本或最优解。
边界条件
边界条件是指问题在某些特定情况下的限制条件。在树型 动态规划中,边界条件通常用于确定问题的起始和终止状 态。
边界条件有助于缩小问题的解空间,提高计算效率。在树 型动态规划中,我们需要根据问题的特性,合理设置边界 条件,以简化计算过程并获得正确的解。
03
树型动态规划的常见问题
区间dp问题
算法改进与优化
针对现有算法的瓶颈和缺陷,进行改进和优化, 以提高算法的效率和适用范围。
理论分析与证明
深入分析树型动态规划算法的理论基础和性质, 如时间复杂度、空间复杂度、最优解的性质等, 为算法设计和改进提供理论支持。
感谢观看
THANKS
总结词
区间dp问题是指给定一个区间,求 出该区间内所有子区间的最大值或最 小值的问题。
详细描述
区间dp问题可以通过动态规划来解决 ,将问题分解为多个子问题,并利用 状态转移方程来求解。常见的区间dp 问题包括区间求和、区间查找等。
动态规划讲解大全(含例题及答案)
多阶段决策过程的最优化问题。 在现实生活中,有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在 它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果。当然,各个阶段决策的选取不 是任意确定的,它依赖于当前面临的状态,又影响以后的发展,当各个阶段决策确定后,就组成一个 决策序列,因而也就确定了整个过程的一条活动路线,如图所示:(看词条图) 这种把一个问题看作是一个前后关联具有链状结构的多阶段过程就称为多阶段决策过程,这种问 题就称为多阶段决策问题。
在前面的例子中,第一个阶段就是点 A,而第二个阶段就是点 A 到点 B,第三个阶段是点 B 到点 C,而第四个阶段是点 C 到点 D。
状态:状态表示每个阶段开始面临的自然状况或客观条件,它不以人们的主观意志为转移,也称 为不可控因素。在上面的例子中状态就是某阶段的出发位置,它既是该阶段某路的起点,同时又是前 一阶段某支路的终点。
fout.close(); return 0; }
USACO 2.3 Longest Prefix
题目如下: 在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的。生物学家对于把长的序 列分解成较短的(称之为元素的)序列很感兴趣。 如果一个集合 P 中的元素可以通过串联(允许重复;串联,相当于 Pascal 中的 “+” 运算符) 组成一个序列 S ,那么我们认为序列 S 可以分解为 P 中的元素。并不是所有的元素都必须出现。 举个例子,序列 ABABACABAAB 可以分解为下面集合中的元素: {A, AB, BA, CA, BBC} 序列 S 的前面 K 个字符称作 S 中长度为 K 的前缀。设计一个程序,输入一个元素集合以及一 个大写字母序列,计算这个序列最长的前缀的长度。 PROGRAM NAME: prefix INPUT FORMAT 输入数据的开头包括 1..200 个元素(长度为 1..10 )组成的集合,用连续的以空格分开的字 符串表示。字母全部是大写,数据可能不止一行。元素集合结束的标志是一个只包含一个 “.” 的行。 集合中的元素没有重复。接着是大写字母序列 S ,长度为 1..200,000 ,用一行或者多行的字符串 来表示,每行不超过 76 个字符。换行符并不是序列 S 的一部分。 SAMPLE INPUT (file prefix.in) A AB BA CA BBC . ABABACABAABC OUTPUT FORMAT 只有一行,输出一个整数,表示 S 能够分解成 P 中元素的最长前缀的长度。 SAMPLE OUTPUT (file prefix.out) 11 示例程序如下: #include <stdio.h>
动态规划动态转移方程大全
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]+w,f[i-1,j]);3. 线性动态规划1-----朴素最长非降子序列F:=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);6. 剖分问题3------乘积最大f[i,j]:=max(f[k,j-1]*mult[k,i]);7. 资源问题3-----系统可靠性(完全背包)F[i,j]:=max{f[i-1,j-c*k]*P[I,x]}8. 贪心的动态规划1-----快餐问题F[i,j,k]:=max{f[i-1,j',k']+(T-(j-j')*p1-(k-k')*p2) div p3}9. 贪心的动态规划2-----过河f=min{{f(i-k)} (not stone){f(i-k)}+1} (stone); +贪心压缩状态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.l,k]+f[t.r,j-k-1]+c}13. 计数问题1-----砝码称重f[f[0]+1]=f[j]+k*w[j];(1<=i<=n; 1<=j<=f[0]; 1<=k<=a;)14. 递推天地1------核电站问题f[-1]:=1; f[0]:=1;f:=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 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),f[i,p,k+len[j]]+f[p+1,j-1,0]}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=y[j]);max{f[i,j-1]+f[i-1,j]}} (i>0,j>0,x<>y[j]);22. 最大子矩阵2-----最大带权01子矩阵O(n^2*m)枚举行的起始,压缩进数列,求最大字段和,遇0则清零23. 资源问题4-----装箱问题(判定性01背包)f[j]:=(f[j] or f[j-v]);24. 数字三角形1-----朴素の数字三角形f[i,j]:=max(f[i+1,j]+a[I,j],f[i+1,j+1]+a[i,j]);25. 数字三角形2-----晴天小猪历险记之Hill同一阶段上暴力动态规划if[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:=f[j]+1;(abs(x-x[j])+abs(y-y[j])<=t-t[j])31. 树形动态规划3-----贪吃的九头龙32. 状态压缩动态规划1-----炮兵阵地Max(f[Q*(r+1)+k],g[j]+num[k])If (map and plan[k]=0) and((plan[P] or plan[q]) and plan[k]=0)33. 递推天地3-----情书抄写员f:=f[i-1]+k*f[i-2]34. 递推天地4-----错位排列f:=(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+g[j];(if sum=Aim then getout; if sum<Aim then inc(i) else inc(j);)42 线性动态规划5-----隐形的翅膀min:=min{abs(w/w[j]-gold)};if w/w[j]<gold then inc(i) else inc(j);43 剖分问题5-----最大奖励f:=max(f,f[j]+(sum[j]-sum)*i-t44 最短路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:=max{f[j]+1}+枚举中央结点48 资源问题------明明的预算方案:加花的动态规划f[i,j]:=max(f[i,j],f[l,j-v-v[fb]-v[fa]]+v*p+v[fb]*p[fb]+v[fa]*p[fa]);49 资源问题-----化工场装箱员50 树形动态规划-----聚会的快乐f[i,2]:=max(f[i,0],f[i,1]);f[i,1]:=sigma(f[t^.son,0]);f[i,0]:=sigma(f[t^.son,3]);51 树形动态规划-----皇宫看守f[i,2]:=max(f[i,0],f[i,1]);f[i,1]:=sigma(f[t^.son,0]);f[i,0]:=sigma(f[t^.son,3]);52 递推天地-----盒子与球f[i,1]:=1;f[i,j]:=j*(f[i-1,j-1]+f[i-1,j]);53 双重动态规划-----有限的基因序列f:=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:=max{f[j]}+P[I]; (e[j]<s)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,j]+f[r,I,k-j-1]},f[f[l,r,j]+f[r,r,k-j]+w[I,r]]}58 树形动态规划-----CTSC 2001选课F[I,j]:=w(if i∈P)+f[l,k]+f[r,m-k](0≤k≤m)(if l<>0)59 线性动态规划-----多重历史f[i,j]:=sigma{f[i-k,j-1]}(if checked)60 背包问题(+-1背包问题+回溯)-----CEOI1998 Substractf[i,j]:=f[i-1,j-a] or f[i-1,j+a]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]+w ords[s]}62 线性动态规划-----最少单词个数f[i,j]:=max{f[I,j],f[u-1,j-1]+l}63 线型动态规划-----APIO2007 数据备份状态压缩+剪掉每个阶段j前j*2个状态和j*2+200后的状态贪心动态规划f:=min(g[i-2]+s,f[i-1]);64 树形动态规划-----APIO2007 风铃f:=f[l]+f[r]+{1 (if c[l]<c[r])}g:=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] or f[i-1,j-a]68 目标动态规划----- Vijos 1037搭建双塔问题F[value,delta]:=g[value+a,delta+a] or g[value,delta-a]69 树形动态规划-----有线电视网f[i,p]:=max(f[i,p],f[i,p-q]+f[j,q]-map[i,j])leaves>=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:=max(f[i-1]+b,b); 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](ss[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]min{}}75 概率动态规划-----聪聪和可可(NOI2005)x:=p[p[i,j],j]f[I,j]:=(f[x,b[j,k]]+f[x,j])/(l[j]+1)+1f[I,i]=0f[x,j]=176 概率动态规划-----血缘关系F[A, B]=(f[A0, B]+P[A1, B])/2f[I,i]=1f[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<j78 线性动态规划-----舞蹈家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[I,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)每个节点记录最大的两个值,并记录这最大值分别是从哪个相邻节点传过来的。
树形动态规划PPT课件
例四、问题描述
学校开设了 N(N<300)门的选修课程,每 个学生可选课程的数量 M 是给定的。学生选 修了这 M 门课并考核通过就能获得相应的学 分。 在选修课程中,有些课程可以直接选修, 有些课程有一门直接的先修课。 你的任务是为自己确定一个选课方案,使得你 能得到的学分最多,并且必须满足先修课优先 的原则。假定课程之间不存在时间上的冲突。
引言
大多数动规都是在一维二维这种规则的 背景下的,可以解决的问题比较局限, 而树作为一种特殊的图,可以描述比较 复杂的关系,再加上树的递归定义,是 一种非常合适动规的框架,树型动态规 划就成为动规中很特殊的一种类型。
树
有n个点,n-1条边的无向图,任意两顶点间 可达 无向图中任意两个点间有且只有一条路 一个点至多有一个前趋,但可以有多个后继 无向图中没有环
动态规划
最优子结构:一个最优化策略的子策略 总是最优的。
无后效性:当前决策与过去状态无关。
引言
因为树可以描述比较复杂的关系,这对 选手分析问题的能力有较高的要求,在 寻找最优子结构、组织状态时往往需要 创造性思维,而且树型动态规划对数学 要求不高,不涉及单调性优化等方面, 所以竞赛中往往将它作为侧重考察选手 分析思考能力的题型出现。
树型动态规划
JSOI2010冬令营
动态规划
问题可以分解成若干相互联系的阶段, 在每一个阶段都要做出决策,全部过程 的决策是一个决策序列。要使整个活动 的总体效果达到最优的问题,称为多阶 段决策问题。动态规划就是解决多阶段 决策最优化问题的一种思想方法。
动态规划
阶段:将所给问题的过程,按时间或空间特征分解成若干相互联系的阶段,以便 按次序去求每阶段的解。 状态:各阶段开始时的客观条件叫做状态。 决策:当各段的状态取定以后,就可以做出不同的决定,从而确定下一阶段的状 态,这种决定称为决策。 策略:由开始到终点的全过程中,由每段决策组成的决策序列称为全过程策略, 简称策略。 状态转移方程:前一阶段的终点就是后一阶段的起点,前一阶段的决策选择导出 了后一阶段的状态,这种关系描述了由k阶段到k+1阶段状态的演变规律,称为 状态转移方程。 目标函数与最优化概念:目标函数是衡量多阶段决策过程优劣的准则。最优化概 念是在一定条件下找到一个途径,经过按题目具体性质所确定的运算以后,使全 过程的总效益达到最优。
动态规划题目选讲
例题二:加分二叉树
• 设一个n个节点的二叉树tree的中序遍历为( l,2,3,…,n),其中数字1,2,3,…,n为节点编号 。每个节点都有一个分数(均为正整数),记第 i个节点的分数为di,tree及它的每个子树都有 一个加分,任一棵子树(也包含tree本身的分数 • 若某个子树为主,规定其加分为1,叶子的加 分就是叶节点本身的分数。不考虑它的空子树。 • 试求一棵符合中序遍历为(1,2,3,…,n)且 加分最高的二叉树tree。
思考
例题六
• 对于 k=0 的情况: • 我们发现遍历一棵树最后回到原点,那么对于所 有的边,我们都是走过去,再走回来。 • 答案 (n-1)*2
例题六
• 对于 k=1 的情况 • 设每条边长度为1,然后树上找最长链,然后这 条链走过去就不再一步步往回了,直接从链底连 一条边去链顶,然后链中间连的那些点,直接走 过去再走回来,它们那些边的答案是不变的。 • 答案 (n−1)*2−(最长链长度)+1 • 可以证明不能减得更多啦。
• 资源和含有工厂的星球个数都不超过4 • n≤200
想法
暴力枚举匹配方案,求最短路?
想法
暴力枚举匹配方案,求最短路? 两条路径公用边怎么办?
思考
• 特殊的星球数量很少,可以枚举状态28=256
思考
• 特殊的星球数量很少,可以枚举状态28=256 • 如何表示状态?
• 设F[i][s]表示现在路径包含第i个星球, 已经连接上的特殊星球选择方案是s的最 少代价。 • 如何转移?
• 对于s的合并操作,枚举!
void Spfa(int s,int k){ int u,v,d,t; for(int top=1;top<=bot;top++){ u=Q[top]; for(int j=E[u].size()-1;j>=0;j--){ v=E[u][j];d=D[u][j];t=s|S[v]; if(F[u][s]+d*k<F[v][t]){ F[v][t]=F[u][s]+d*k; if(t==s&&V[v][s]){ V[v][s]=false;Q[++bot]=v; } } } V[u][s]=true; } }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
动态规划专题(六):树型动态规划(重庆巴蜀中学黄新军)信息学竞赛中通常会出现这样的问题:给一棵树,要求以最少的代价(或取得最大收益)完成给定的操作。
有很多问题都是在树和最优性的基础上进行了扩充和加强,从而变成了棘手的问题。
这类问题通常规模较大,枚举算法的效率无法胜任,贪心算法不能得到最优解,因此要用动态规划解决。
和一般动态规划问题一样,这类问题的解决要考虑如下三步:1、确立状态:几乎所以的问题都要保存以某结点为根的子树的情况,但是要根据具体问题考虑是否要加维,加几维,如何加维。
2、状态转移:状态转移的变化比较多,要根据具体问题具体分析,这也是本文例题分析的重点。
3、算法实现:由于模型建立在树上,即为树型动态规划。
【例题1】二叉苹果树【问题描述】有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点),这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。
我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。
下面是一颗有4个树枝的树:现在这颗树枝条太多了,需要剪枝。
但是一些树枝上长有苹果。
给定需要保留的树枝数量,求出最多能留住多少苹果。
【文件输入】第1行2个数,N和Q(1<=Q<=N,1<N<=100)。
N表示树的结点数,Q表示要保留的树枝数量。
接下来N-1行描述树枝的信息。
每行3个整数,前两个是它连接的结点的编号。
第3个数是这根树枝上苹果的数量。
每根树枝上的苹果不超过30000个。
【文件输出】输出文件仅一个数,表示最多能留住的苹果的数量。
【样例输入】5 21 3 11 4 102 3 203 5 20【样例输出】21【思路点拨】由题意可知,需要保留的树枝数量为Q条,即保留结点t=Q+1个。
树根必须保留,可以分三种情况讨论保留苹果的最大数。
①树根的左子树为空,全部保留右子树,右子树中保留t-1个结点;②树根的右子树为空,全部保留左子树,左子树中保留t-1个结点;③树根的两棵子树都为非空,设左子树保留k个结点,则右子树保留t-k-1个结点。
要得到保留树根时的苹果最大数,只需要求上述三个方案中的最大值。
设树根为V,左儿子为ch[v,1],右儿子为ch[v,2],对于①方案,要取得该方案的最大值,需要取得以ch[v,2]为根,保留t-1个结点的最大值。
这时同样具有上述三种方案。
其他②③情况同理;由此可以看出,该问题具有明显的最优子结构性质,每个问题都与左右儿子结点有关系,但不与孙子结点发生关系,具备无后效性;且计算方案时,搜索子结构时具备重叠性,所以可以用动态规划来解决。
阶段和状态:f[v,t]:表示以v为根的树上保留t个节点的最大权值和。
设ch[v,1],ch[v,2]分别存v节点的左右孩子。
状态转移方程:f[v,t]=max{f[ch[v,1]][i]+f[ch[v,2]][t-i-1]+num[v]}(0<=i<=t-1)初始化:f[v,t]=0,(t=0);f[v,t]=num[v];(ch[v,1]=0且ch[v,2]=0)Answer=f[1,t];【例题2】加分二叉树(NOIP2003)【问题描述】设一棵n个结点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为结点编号。
每个结点都有一个分数(均为正整数),记第i个结点的分数为di,tree及它的每个子树都有一个加分,任一棵子树subtree(也包含tree本身)的加分计算方法如下:subtree的左子树的加分×subtree的右子树的加分+subtree的根的分数若某个子树为空,规定其加分为1,叶子的加分就是叶结点本身的分数。
不考虑它的空子树。
试求一棵符合中序遍历为(1,2,3,…,n)且加分最高的二叉树tree。
要求输出;(1)tree的最高加分(2)tree的前序遍历【输入格式】第1行:一个整数n(n<30),为结点个数。
第2行:n个用空格隔开的整数,为每个结点的分数(分数<100)。
【输出格式】第1行:一个整数,为最高加分(结果不会超过4,000,000,000)。
第2行:n个用空格隔开的整数,为该树的前序遍历。
【输入样例】55 7 1 2 10【输出样例】1453 1 24 5【思路点拨】本题已经说明了问题的模型是一棵树,而且是一棵中序遍历为1,2,3,…,n的二叉树。
而对于一棵中序遍历为1,2,3,…,n的二叉树有很多种形式,对于样例,下图就列出了3种形式,而按题意,第三种形式得到的得分最大。
性质:中序遍历是按“左-根-右”方式进行遍历二叉树,因此二叉树左孩子遍历序列一定在根结点的左边,右孩子遍历序列一定在根结点的右边!因此,假设二叉树的根结点为k,那么中序遍历为1,2,…,n的遍历序列,左孩子序列为1,2,…,k-1,右孩子序列为k+1,k+2,…,n,如下图:我们思考的方式变为,要使得整棵树最优,必须左孩子和右孩子都最优,因此设f[i][j]表示以结点i,i+1,i+2…,j组成的二叉树所得的最大加分;设根为k,则枚举根结点。
d[k]表示k结点的最大分值;故有:f[i,j]=max{f[i,k-1]*f[k+1,j] +d[k]};(1<=i<=k<=j<=n)初始条件:f[i,i]=d[k]Answer=f[1,n]时间复杂度:O(n3)题目还要求输出最大加分树的前序遍历序列,因此要构造这个树,我们只需记录每次的决策值,令p[i,j]=k,表示中序遍历为i,i+1,…,j的二叉树的取最优决策时的根结点为k,最后前序遍历这个树即可。
【例题3】选课(CTSC1997)【问题描述】大学里实行学分。
每门课程都有一定的学分,学生只要选修了这门课并考核通过就能获得相应的学分。
学生最后的学分是他选修的各门课的学分的总和。
每个学生都要选择规定数量的课程。
其中有些课程可以直接选修,有些课程需要一定的基础知识,必须在选了其他的一些课程的基础上才能选修。
例如,《数据结构》必须在选修了《高级语言程序设计》之后才能选修。
我们称《高级语言程序设计》是《数据结构》的先修课。
每门课的直接先修课最多只有一门。
两门课也可能存在相同的先修课。
为便于表述每。
下面举例说明:上例中1是2的先修课,即如果要选修2,则1必定已被选过。
同样,如果要选修3,那么1和2都一定已被选修过。
学生不可能学完大学所开设的所有课程,因此必须在入学时选定自己要学的课程。
每个学生可选课程的总数是给定的。
现在请你找出一种选课方案,使得你能得到学分最多,并且必须满足先修课优先的原则。
假定课程之间不存在时间上的冲突。
【文件输入】输入文件的第一行包括两个正整数M,N(中间用一个空格隔开),其中M表示待选课程总数(1<=M<=1000),N表示学生可以选的课程总数(1<=N<=M)。
接下来M行,每行代表一门课,课号依次为1,2,…,M。
每行有两个数(用一个空格隔开),第一个数为这门课的先修课的课号(若不存在先修课则该项为0),第二个数为这门课的学分。
学分不超过20的正整数。
【文件输出】输出文件只有一行为一个数,即实际所选课程的学分总数。
【样例输入】7 42 20 10 42 17 17 62 2【样例输出】13【思路点拨】本题与二叉苹果树的显著区别为输入数据是森林或一颗普通有序树,相对于二叉树来说,更复杂些。
对于此情况,可以把森林或普通有序树转换成二叉树,再进行DP设计。
下面分两个步骤来分析此问题:(1)转换树。
输入数据为一棵普通有序树或者森林,根据树的转换规则,把右子树转换成左子树的右儿子,或者右边的一棵树转换成左边树根的儿子。
cin>>n>>m;for(i=1;i<=n;i++){ cin>>k>>v;a[i].value=v;if(son[k]==0)a[k].left=i;else a[son[k]].right=i;son[k]=i;}(2)树上的动态规划创建。
以结点i为阶段,以选的课程数j为状态,以到达叶子结点为边界,以每个结点能取得的最高得分为决策,在整棵树上的决策构成一个决策序列。
用f[i][j]表示结点i为根的子树中取j门课程的最高得分,对树型结构分2种情况进行动态规划设计。
①由于是普通有序树或森林转换成的二叉树,所以需要对右子树进行特殊处理。
当只有右子树时,此时i结点不能选,只能选择i结点的右子树,即选择课程数为j。
所以此时的状态转移方程为:f[i][j]=f[i.r,j]。
②由于要选择左子树时,树根必须选择,所以可以把只有左子树和左右子树都有两种合并起来进行考虑,得到动态规划方程为:f[i][j]=max{f[i.l][k]+f[i.r][j-k-1]+a[i]}(0<=k<=j-1) 最后取①②两种情况中的最大值,即可得到在i结点处取j门课程的最大值。
时间复杂度:O(n2m)【例题4】数字转换【问题描述】如果一个数x的约数和(不包括它本身,下同)比它本身小,那么x可以变成它的约数和;如果对于某个y>x且y的约数和为x,那么x也可以变成y。
例如,4可以变为3,1可以变为7。
限定所有的数字变换在不超过n的正整数范围内进行,求不断进行数字变换且没有重复数字出现的最多变换步数。
【文件输入】输入一个正整数n【文件输出】输出不断进行数字变换且没有重复数字出现的最多变换步数。
【样例输入】7【样例输出】3【样例说明】一种方案为:4→3→1→7。
【数据范围】n<=50 000。
【思路点拨】先预处理出每个数的约数,然后很明显就是求树的最长链问题。
一棵有根树的最长链,可能出现如下图的两种情况:对于每个结点我们都要记录两个值:d1[i]表示以i为根的子树中,i到叶子节点的距离最大值;d2[i]表示以i为根的子树中,i到叶子节点的距离次大值;令j是i的儿子。
则:①若d1[j]+1>d1[i],则d2[i]=d1[i]; d1[i]=d1[j]+1;②否则,若d1[j]+1>d2[i],则d2[i]=d1[j]+1;最后扫描所有的结点,找最大的d1[i]+d2[i]的值。
【例题5】战略游戏【问题描述】Bob喜欢玩电脑游戏,特别是战略游戏。
但是他经常无法找到快速玩过游戏的办法。
现在他有个问题。
他要建立一个古城堡,城堡中的路形成一棵树。
他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能瞭望到所有的路。
注意:某个士兵在一个结点上时,与该结点相连的所有边将都可以被瞭望到。
请你编一程序,给定一树,帮Bob计算出他需要放置最少的士兵。
【文件输入】输入文件中数据表示一棵树,描述如下:第一行N,表示树中结点的数目。