[DP][CDQ分治][树状数组] bzoj2244 SDOI2011 拦截导弹

题目链接

题意:

给定一个序列,每个元素有两个属性 $h$ 和 $v$ ,是导弹的高度和速度,发射的拦截炮弹第一发可以是任意的高度和速度,但是要求每一发炮弹的高度和速度都不能大于前一发。问:
1. 选取最优的发射方案的时候最多能拦截多少发导弹
2. 当有多个拦截导弹数目相同的最优方案的时候,我方会从中随机选取一种方案,现在问在这种策略下,每发炮弹能拦截到导弹的概率是多少

题解:

第一问很明显使用cdq分治加速dp转移算LIS,难点在于第二问。把LIS各个节点的转移看成图上的连边的话,可以得到一个dag,而后可以想见使用dp求出到每个点的在LIS上的路径有多少条,便可以确定随机选取的情况下每个节点被选取到的概率为 经过该点的在LIS上的路径数/所有的在LIS上的路径数 。判断一个点是否在LIS上,我们可以两端各求一次LIS,分别记为 $dpl[i] dpr[i]$ ,则如果当前节点满足 $dpl[i]+dpr[i]=\max\limits_{1\le j\le n} dpl[j]+1$ 则说明其属于某个LIS,+1是为了去除节点本身的重复计算。 为了求出经过某个点的路径数,我们可以用之前 dp求最短路必经边的方法 ,从两端分别跑一次dp,分别记录两端到某个节点的属于LIS的路径数为 $gl[i]\;gr[i]$ ,这样的话经过节点i的路径数就可以表示为 $gl[i]*gr[i]$ ,则每个点被选中的概率就可以被表示为

$$\frac{gl[i]*gr[i}{\sum_{[dpl[k]=LIS]}gl[k]}$$

这就是第二问的答案了。因为分治中每次需要对 $[l,r]$ 之间的元素暴力排序,所以复杂度会多一个 $log$ ,也就是 $\mathcal{O}(n\log{}n)$
继续阅读“[DP][CDQ分治][树状数组] bzoj2244 SDOI2011 拦截导弹”

[比赛补题][线段树+][动态维护矩阵乘法][动态dp][区间lr问题] codeforces 750E New Year and Old Subsequence

题目链接

题意:

类似上一题,给定一个长度2e5的字符串,2e5个询问,每次问从区间 [l,r] 里面最少删去多少而可以使得结果中存在2017但是不存在2016。这个是比较好的一道题,之前我从没来遇到过动态维护动态规划的。。。这叫什么,动态动态规划?(雾)

题解:

首先考虑简单版的问题,如果不考虑查询,单次做问整个序列最少去掉多少该怎么做?我当时是考虑了很多,但是如果按照正常的考虑方式的话就会越想越复杂,不知道该维护什么样的一个状态。该以什么作为状态呢?如果按照状压的思路会发现无法转移,因为他这个2016和2017都是有顺序的啊,不能状压搞,但是也不能把前面的所有情况搞出来,复杂度会爆炸。看了题解发现有人提正则表达式和有限状态机才明白了。。。之前做的那个题简单是因为他很好转移,是不包含当前前缀时最少需要删除多少,而这个题目的状态需要定义为包含当前状态机节点对应的前缀且不包含严格包含当前状态机节点对应的前缀最少需要删除多少个字符。。。意思就是20的时候不能有201和2017的时候的需要删除的最少字符。。

然后考虑状态的转移,这个有限状态机可以匹配出来2017,但是匹配出来之后呢?我们应该拒绝掉所有的2016,注意这时候,从状态2017和201都可以转移到2016,所以我们当前如果已经匹配完且达到2017/201的时候,转移回到本身都需要多删掉一个字符,也就是本身。。。其他情况是如果要往下一个节点走的时候,回到自身的代价是1,往下走的代价是0.。。其实也就是一个选择,选择当前的这个字符留还是不留,,,,跟谁匹配的话比较好。。

然后他很妙的一点就是这个转移可以写成矩阵的形式,当然这不是一个矩阵乘法,是一个很怪的操作,类似Floyd最短路的方法,然后这个矩阵操作是满足结合律的(我也不知道为什么满足结合律)。。。。就可以用线段树维护了。。。

甚至说这个题甚至可以改成带修的。。

继续阅读“[比赛补题][线段树+][动态维护矩阵乘法][动态dp][区间lr问题] codeforces 750E New Year and Old Subsequence”

[区间DP][双DP][×] UVA 1579&Gym 10128H Matryoshka

紫书DP课后题最后一题了,也算是把这一部分做完了吧。
这个题,在uva上的数据太水了,导致很多网上的题解代码是错误的。在gym10128H这里会wa。这些题解大多是用一个简单的贪心策略处理分段,然后用区间dp处理分出来的段落。但是实际上分段也需要用一个dp,比如数据 1 2 4 3 1 2,用简单的贪心分段就会把4 3分到前面那一段,这样的出来结果是5(当把1 2 放进4 3里的时候4和3都要打开),但是如果把4 3分到后面的1 2里答案是4,是更优的解。

先讲简单的部分:分好段之后的区间dp。这个就是普通的区间dp $$dp(l,r)=min(dp(l,i)+dp(i+1,r)+cost(l,i,i+1,r)),i\in[l,r)$$其中 \[dp(l,r)\]表示
[l,r]之间的套娃组装成1个所需要的最小花费, 继续阅读“[区间DP][双DP][×] UVA 1579&Gym 10128H Matryoshka”