一、树形DP
1.POI2017 ssoj3901: Sabota?
题目:
某个公司有n个人, 上下级关系构成了一个有根树。其中有个人是叛徒(这个人不知道是谁)。对于一个人, 如果他下属(直接或者间接, 不包括他自己)中叛徒占的比例超过x,那么这个人也会变成叛徒,并且他的所有下属都会变成叛徒。你要求出一个最小的x,使得最坏情况下,叛徒的个数不会超过k。1<=k<=n<=500000
题解:
一开始的思路是二分x,然后根据在这种情况下,一个节点的孩子是否可能全是叛徒来从下至上递推,完成判定。然而此题对精度要求极高,二分会TLE,故考虑一个O(N)的做法。由于刚才判定的方法类似树形DP,故考虑设计一个易于转移的状态,发现对于一颗子树,我们关心的只是它是否能全部变为叛徒,故记f[i]为i的子树不全变为叛徒的最小x,枚举所有子树,要么使它不全为叛徒,要么使它即使全为叛徒,也不影响,取所有子树的最大值即为该子树的答案,取大小大于k的子树的最大值即可。
2.bzoj2782 ssoj1821: 经典游戏 (game)
题目:
SUPER M是一个很经典的游戏
现在改一下规则
有N个城堡(0到n-1)
每个城堡都有一个KOOPA,注意:有些KOOPA会可能有1个FATHER-KOOPA
公主在最后一个城堡内(N-1)
现在每次只能打一个城堡且必须在T[I]时间内打完(否则游戏结束)
如果(N-1)号城堡打完
游戏结束
如果一个KOOPA至少有2个SON-KOOPA被打败
则必须马上去击败这个KOOPA否则会因为愤怒而做掉公主
现在求
最长游戏时间
N<=1e5
题解:
发现与n-1号点不连通的点是没用的,故只考虑以n-1号点为根的子树,对于它的所有儿子的子树,只能将其中一个全部打掉,其他尽量打,但不能打到根,还有一个一打到根就退出,因为这样已有两个儿子被打了,游戏结束。那么我们只需求出它的子树的这些值,然后求最大值即可,而它的子树的这些值又由它子树的孩子决定,故考虑树形DP,记f[i]为打到根就退出,g[i]为不打到根,s[i]为子树所有节点的权值,f[i]由题意转移,g[i]由一个子树打满,其他字数打到根的最大值,s[i]直接累加,转移完毕。
二、状压DP
题目
1.usaco-2013-Nov ssoj1770: 不设找零 No Change (nochange)
FJ正在市场上为他的农场采购日用品,他口袋里有K(1<=K<=16)个硬币,每一个硬币的面值均在1~1,00,000,000之间。FJ有一个包含N(1<=N<=100,000)种待购物品的序列清单,其中第i种物品需要的钱数为c(i),(1<= c(i) <=10,000),在购物的过程中,物品必须按照清单顺序购买,他随时可以停下来用一枚硬币付一次钱,每次付钱的对象为从上次付钱之后至当前所有物品价值和(当然,他所付的硬币面值也必须足够大),不巧的是,市场上的商户们都没有零钱了,因此如果FJ给的硬币面值大于所购物品价值,他也不会得到找零!
请计算FJ完成N件物品的购物后,所能剩下的最大钱数。如果他无法买到所有物品,输出-1。
题解
看到k那么小,自然想到状压每个硬币是否用过,但按照正常的DP,都要记录买到第几个,而这题状压玩后显然不能再多一维n,况且,如果已知用过的硬币及买到第几个,F里只能记是否满足,这显然浪费了,因此我们直接在F中记用这些硬币能买到的最多物品,转移时枚举没用过的硬币,二分即可。
三、与组合数学有关的DP
1.ssoj1179: 高楼 skyscraper
题目:
相信大家都做过这样一个问题:
话说某国的总共有N栋高楼,高楼们都排成一条直线且高度两两不相等。从一边看过去,会有某些楼被前面更高的楼挡住。已知从这些楼的左边看可以直接看到L栋高楼,从右边看可以看到R栋。请问有多少种高楼的排列方案满足这个条件。N<=5000
题解:
注意到最高的那栋高楼一定会被看到,所以我们枚举最高的楼的位置,分成左右两半,要求的是一个相同的问题:i栋高楼看到j栋的方案数。原来的想法是假设第i栋楼为最高,枚举上一个最高的楼,乘上排列数进行转移。但这是O(N^3)的,故考虑如何才能不用枚举。既然要O(1)转移状态,就要只考虑第i个栋楼,而当第i栋楼比前面i-1栋楼中的一些高时,就需考虑前i-1栋楼,所以我们要使第i栋楼最低,那么就从高到底考虑,这样讨论第i栋楼是否能被看见即可高效转移。
2.1282: 排列计数 perm
称一个1,2,…,N的排列P1,P2…,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,…N的排列中有多少是Magic的,答案可能很大,只能输出模P以后的值
题解:
因为从后往前不好看,故从前往后看,发现对于a[i],a[i2],a[i2+1]都要大于它,且a[i2],a[i2+1]也是如此,那么,这个递归的过程就可以看做一颗完全二叉树,再加上大小的限制,即是一个小根堆。那么,既然是一颗树,考虑从一个节点的孩子转移到这个节点,对于1-i的排列,1一定在根节点,左右子树可任意分配,乘上一个组合数,再乘上左右两边的方案数即可,那么子树虽然其元素是离散的,但其相对大小关系仍可看做一个排列,故往下递推即可。
四、利用题目性质的DP
1.POI2013 ssoj2057: Bytecomputer
题目:
给定一个{-1,0,1}组成的序列,你可以进行x[i]=x[i]+x[i-1]这样的操作,求最少操作次数使其变成不降序列。N<=1e6
题解:
原来的想法是记f[i][j]为前i个数,最后一个数为j的方案数,是O(N^2)的。考虑能优化的只有j这一维,故想到最后一个数的情况应该不会很多,根据题意猜想只有-1,0,1这三种情况,然后考虑证明:对于第一个变玩后大于1的数,则它前一个数一定是1,那么原来的这个数一定可以变为1,这样就满足条件了,比变为大于1更优,小于-1则会小于第一个数(因为第一个数不变)根本不可能满足条件。故分类讨论一下,不难转移。
五、与贪心结合的DP
1.usaco-2013-Mar-Gold ssoj1443: 奶牛逃亡(cowrun)
题目:
Farmer John忘记修复他农场篱笆上的一个大洞,以至于篱笆围着的N(1<= N <=1,000)只奶牛从大洞中逃脱出来,并在农场里横冲直撞。每头在篱笆外的奶牛每分钟都将给他带来一美元的损失。FJ必须遍及每头奶牛、安抚它们来停止这些损失。幸运的是,这些奶牛被定位在农场外的直线道路上的不同位置。 FJ知道每头奶牛相对于FJ的位置P_I(-500,000<= P_I的<=500000,P_I=0),FJ所处的位置记为位置0。FJ每分钟可以移动一个单位的距离,并可以当即完成对奶牛的安抚,停止他们造成的损失。请确定FJ安抚奶牛的顺序,使得他可以最大限度地减少经济损失,并计算出在此顺序下的总损失。
题解
看到题目,如果不知道顺序的话,一开始感觉要记的状态很多的样子(每头奶牛是否被安慰过),所以考虑能不能先找出一个大概的顺序。发现沿着一个方向走,每碰见一头奶牛都要安慰,这样一定更优,所以在原点同侧,安慰的顺序一定是坐标绝对值从小到大的,这样安慰过的奶牛就是一段前缀,那么状态就好办了,记f[i][j]为左边安慰了前i头,右边安慰了前j头的最小损失,转移显然。
六、区间DP
ssoj3967: 计数(count)
既然是萌萌哒 visit_world 的比赛,那必然会有一道计数题啦!
考虑一个 N个节点的二叉树,它的节点被标上了 1∼N 的编号. 并且,编号为 i的节点在二叉树的前序遍历中恰好是第i个出现.
我们定义Ai 表示编号为i的点在二叉树的中序遍历中出现的位置.
现在,给出M个限制条件,第i个限制条件给出了ui,vi,表示Aui<Avi ,也即中序遍历中ui在vi之前出现.
你需要计算有多少种不同的带标号二叉树满足上述全部限制条件,答案对109+7 取模.
题解
我们要解决的是前序为1-n的所有节点构成树的形态数,那么前序为1的必然是根节点,枚举i,2-i的是左子树,i+1到n的是右子树,累计左右子树答案之积的和,看出这是一个递归的过程,且对于每一个任务,我们关心的只有左右端点,故考虑DP,转移显然,但还要考虑条件限制:右子树及根不能对左子树有限制,且右子树不能对根有限制,而他们的编号又是一段连续区间,而限制又是一个二维问题,故用矩阵前缀和处理即可。
七、与数据结构有关的DP
1.栈
ssoj2480: 最长合法括号序列(lrbs)
题目描述
这是另一道处理合法括号序列的题目。
我们应该提醒你,如果一个括号序列插入“+”和“1”后,可以得到一个正 确的数学表达式,那么它被称为“合法”的。
例如,序列“(())()”,“()”和“(()(()))”是合法的,但“)(”,“(()”和“(()))(”不是。
给出一个由“(”和“)”字符组成的字符串。你要找出它最长的是合法括号序列的子串,也同样要找出最长子串的个数。
题解:
首先要注意审题,题目要求的是子串,即连续的一段,而不是子序列,(因此想偏了好久……)。
因为是子串,故考虑枚举终点,记f[i]为以i为终点的最长串。从左至右扫一遍,如果是“(”,则它要被后面的匹配,故考虑将它“存”起来,那要怎么存呢?发现对右边一个“)",它匹配的一定是最右边的”(“,即后进先出,故丢进栈中,对于一个”)“,找到栈顶的“(”匹配,由于在他们之间的左右括号都已被匹配完,故答案为f[q[tp]]+i-q[tp]+1.
2.树状数组
ssoj1556: 堆积木(klo)
Mary在她的生日礼物中有一些积木。那些积木都是相同大小的立方体。每个积木上面都有一个数。Mary用他的所有积木垒了一个高塔。 妈妈告诉Mary游戏的目的是建一个塔,使得最多的积木在正确的位置。一个上面写有数i的积木的正确位置是这个塔从下往上数第i个位置。Mary决定从现有的高塔中移走一些,使得有最多的积木在正确的位置。请你告诉Mary最多有多少点可以处在正确位置。ai<=1e6,n<=1e5.
题解:
因为是前面的决策影响后面的问题,故考虑DP,而状态只能设计一维,要使它能够记录前面的信息及最大值,故记f[i]为第i个方块在正确位置时的最大值,考虑转移,它必由fj转移而来,而这个j还应满足什么条件呢?发现只能移除,故i与j的位置差不能超过它们的数值差,即i-j<=a[i]-a[j],即a[i]-i>=j-a[j],那么按照a为第一关键字升序,坐标为第二关键字降序(这样保证只有a小的会影响后面),用树状数组维护最大值即可。
八、与概率期望结合的DP:
ssoj2462: 收集(collecting)
题目描述
教育超市最近进行一项促销活动,凡是购物消费就可以获得小玻璃珠一个。喜爱收集小玩意儿的xy当然不会错过这个活动。假定一共有n种颜色的玻璃珠,每次发放玻璃珠的颜色是随机的(即获得每种颜色的玻璃珠的概率是相同的)。xy想知道要收集所有颜色的珠子,期望购买的次数是多少。
题解:
对于无限期望的题目,直接列式子不太好算,而考虑这个问题,要使颜色数多1,若抽到颜色不同的就停止,否则问题又重新转化为原来相同的问题,又可用原来的量来表示,那么就可列方程f[i+1]=(f[i]+1)p+(i-p)(f[i+1]+1),p=(n-i)/n,就解决问题了。