NOIP2018准备——DP总结

一、树形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栋楼是否能被看见即可高效转移。

四、利用题目性质的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头的最小损失,转移显然。

猜你喜欢

转载自blog.csdn.net/sz_165394732/article/details/83475423
今日推荐