完成情况 | 题目 | 出处 |
---|---|---|
Trade | HDU 3401 | |
AC | Parade | HDU 2490 |
轻音乐同好会 | CDOJ 877 | |
诗人小G | BZOJ 1563 [NOI 2009] | |
AC? | MAX Average Problem | HDU 2993 |
AC | 玩具装箱 toy | BZOJ 1010 |
Post office | POJ 1160 | |
AC | 骨牌覆盖 V2 | 51NOD 1033 |
生成树计数 | BZOJ 1494 [NOI 2007] |
1.数据结构优化
2.决策单调性的优化
3.斜率优化
4.四边形不等式优化
5.矩阵快速幂优化
针对 1D/1D 型的 dp ,转移方程大概是 dp[i]=min/max(dp[j]+g(i,j)) ,这样子我们可以用数据结构优化。常用的数据结构有线段树,树状数组,平衡树,单调队列等。
形如 dp[i]=min(dp[j]+g[j]+f[i]) 这种式子,即我们可以写成两段完全不相干的式子,然后针对决策,用一个单调队列优化。
找[l,r]的max。
单调队列的裸题,每次先入队,再查答案。
完全背包问题
这个可以做到 nv 的,具体做法如下:首先完全背包的转移式子是 dp[i][j]=max(dp[i−1][j−v∗k]+w∗k)(0<=k<=n[i])
想办法把其分开,假设 d=v[i],a=j/d,b=j ,即 j=a∗d+b ,代入,并用 k 替换 a−k 得:
dp[i][j]=maxdp[i−1][b+k∗d]−k∗w[i]+a∗w[i](a–n[i]<=k<=a) ,这样子按照余数分类就分开了。
HDU 3401
设dp[i][j]表示第i天有j个股票的最值,然后分别可以得到一些转移,至于优化,我们以买股票为例, dp[i−w−1][k]−APi[i]∗(j−k)=dp[i−w−1][k]+APi[i]∗k−APi[i]∗j(k<j) ,这个就分离了 k ,就可以单调队列搞了。
HDU 2490
Dp[i][j]表示在i行j列的答案,转移是 dp[i][j]=max(dp[i−1][k]+dis[k−>j]) 我们对 k 大于 j 与 k 小于 j 分别讨论,这样子比如大于的话,那么把 dis 写成前缀和的形式,有 dis[k−>j]=sum[j]−sum[k] ,这样我们只需要 dp[i−1][k]−sum[k] 最大的就行了,这个可以单队。至于 k>j ,反过来再搞一遍就可以了。
雪菜为了能让冬马参加轻音乐同好会,瞒着春希,和冬马见面。为了增进感情,雪菜拉着还没缓过神来的冬马进了游戏厅……游戏要求两名玩家在排成一排的n个石头上跳跃前进,每个石头有一个高度,玩家只能向右跳,并且不能跳向比自己所在位置的石头矮的石头。一个石头在一个玩家跳离后就会消失,并且两个玩家不能同时站在同一个石头上。游戏分数为两个玩家站过的石头的总数。游戏起始,两名玩家都可以任选一个石头作为开始位置(当然不能相同)。由于冬马是挂科专家,雪菜又只有英语好,所以她们两人想请你帮助他们,怎么才能让分数最高。
dp[i][j] 表示 i 到 j 的最值,转移的话是 dp[i][j]=max(dp[u][j])+1(a[i]>=a[u])dp[i][j]=max(dp[i][v])+1(a[j]>=a[v]) ,然后这样我们可以发现他实际上是查前缀最值,就可以一个树状数组搞定。
将一个由N个非负数组a[i]成的序列划分成若干段,要求每段数字的和不超过M,求【每段的最大值】的和 的最小的划分方法,输出这个最小的和。
dp[i] 表示 i 个的答案,转移是 dp[i]=dp[k]+max(val[i j]) ,这样子是 n2 的,考虑优化。我们注意到这个还是有一定的单调性的,所以可以拿一个单调队列,但是因为 max 在一直变,所以队头的不一定是最优的,所以我们应该挂一个线段树,查区间最小值。(貌似有点难写)
所谓决策单调性,就是 dp 在转移的时候,决策点是成段上升的,这样我们就可以用一种来维护,我们每算出一个 dp 值,就用它来更新他能管的区间,要怎么更新呢,注意到有单调性,所以可以二分来更新。
那么怎么判断是决策点单增呢,就要满足四边形不等式
∀i≤j,w[i,j]+w[i+1,j+1]<=w[i+1,j]+w[i,j+1]
Bzoj 打字
设dp[i]为i的答案,设前缀数组为 sc ,转移是 dp[i]=mindp[j]+(sc[i]−sc[j])2+m;0<=j<i
那么可以证明这个满足四边形不等式,所以就可以用了
虽然大多数决策单调性的题也可以用斜率优化,但是也有不能的,比如下面这道:
Noi 2009
dp 方程很好写,是 dp[i]=min(dp[j]+|s[i]−s[j]+i−j−1−l|p)
,不是平方,就用不了斜率优化(要是能用,那你怎么展开),但是还是有决策单调性,所以仍然可做。
。
针对 2D/2D 的,形如 dp[i]=min(a[i]×f[j]+b[i]×g[j]) 的转移,这种无法分开的转移,我们设 f[j]=x,g[j]=y,dp[i]=a 所以有 a=min(a[i]x+b[i]y) 相当于是固定斜率,求截距的最值,这个就是维护一个凸包。
还是之前那道打字题。
由 dp 方程可知 dp[i]=sc[i]2+m+mindp[j]+sc[j]2−2sc[i]sc[j] ,那么设 x=sc[j],y=dp[j]+sc[j]2,a=sc[i] ,即求 y−2ax=dp[i] 这个直线,然后维护。
维护的步骤是:
1.去掉头部不符合的解。
2.算出 dp 值。
3.加入 dp 值。
去掉头部不符合的解的方法是判断斜率,当然也可以直接算。
加入 dp 值的方法就是维护图像的凸性,设之前的点为 n1 ,再之前的为 n2 ,那么我们要判断新加入的点n,要判断 n1n,n2n,n1n2 这几条的斜率,实际上可以只判断 n2n 与 n1n 的斜率。
通常的题,可以用斜率优化的话,代价是平方。而且大多数决策单调性的题也可以用斜率优化。
HDU 2993
这个就很裸的维护一个凸包。
Bzoj玩具装箱
设 dp[i] 表示 i 的答案,那么转移方程是: dp(x)=min(dp(i)+w[i+1,x]),w[i,j]=(j−i+sum(c)−L)2 ,那么明显有决策单调性。自然,这道题是平方,所以可以用之前的方法,把它用斜率优化。
如果转移是: f[i,j]=min(f[i,k]+f[k+1,j])+w[i,j] ,(比如区间dp)
如果对于 i≤i′<j≤j′ ,有 w(i′,j)≤w(i,j′) ,那么说明 w 具有区间包含的单调性。
如果对于 i≤i‘<j≤j′ ,有 w(i,j)+w(i′,j′)≤w(i′,j)+w(i,j′) ,我们称函数 w 满足四边形不等式。
可以形象理解为两个交错区间的 w 的和不超过小区间与大区间的 w 的和。
这个四边形不等式有什么作用呢,我们可以证明,如果满足四边形不等式,那么设 s[i,j] 为 dp[i,j] 的决策点,那么有 s(i,j−1)≤s(i,j)≤s(i+1,j) ,所以就可以通过这个性质,把本来的转移平摊下来变成 n 的,相当于是把很多段拼成了一个 n 。
用数轴描述一条高速公路,有V个村庄,每一个村庄坐落在数轴的某个点上,需要选择P个村庄在其中建立邮局,要求每个村庄到最近邮局的距离和最小。
我们设 dp[i,j] 表示 i 到 j 全搞好的代价,转移就是 dp[i][j]=mindp[i−1][k]+w[k+1][j](k<j) ,那么这个 w 满足四边形不等式,可以优化。
主要是优化线性的递推,而且没有 min 之类没有可加性的转移。那么就更算递推数列的某一项一样,矩阵乘法就可以了。
51nod 1033
明显的插头状压 dp ,那么转移就是线性的,但是情况有点多,我们可以打一个暴力算出所有情况,只有很少。
NOI 07年
那么如果要联通,只用 i−5 与前面的联通就可以了(不然没机会了),所以我们可以状压连通性,然后转移,但是情况一样很多,所以还是要用爆搜乱搞。最后搜出来只有 52 种。
就是可以证明 M 的 i 次方也是 M 的 1 次方到 M 的 i−1 次方的线性组合,所以转移系数,用向量来乘,优化成 n2 的(好像没什么用)。
对于 dp 的优化,不同的转移有不同的优化:
1)如果转移可以写成完全分开的部分,可以用单调队列。
2)如果是 1D/1D 的,可以套一个数据结构。
3)如果有决策单调性(考试时可以打表证明),就二分。
4)如果是 2D/2D 而且系数较低(一般不超过二次),就可以斜率优化。
5)对于类似区间 dp 的,考虑四边形不等式。
6)线性递推式用矩阵乘法。