可能需要莽一莽
大佬说是那就是,不狡辩
目录:
(之前的部分在论证理论正确性;如果功利一点、只想解决问题的话,直接从上一部分的最后开始看就行了)
假如对于某一个dp方程,$dp(i)$的最优转移是$dp(k)$,那么称$k$为$i$的决策点
而dp方程满足决策单调性指的是,决策点$k$随着$i$的增大保持单调不减(二维的情况稍微复杂一点,见下面的四边形不等式推决策单调性)
感觉有点类似斜率优化?
我们维护的下凸包,斜率也满足单调不减;所以如果斜率不等式的右侧是单调不减的(即决策时只需要向栈顶走、不需要在栈中二分),那么决策点也是单调不减的
所以绝大多数的斜率优化也满足决策单调性
一维状态dp的决策单调性比较直观,二维状态的就没那么显然了;需要借助其他的东西进行分析
而四边形不等式正是推出决策单调性的有力工具(虽然最后判断决策单调性都是打表)
四边形不等式一般满足这样的格式:
对于函数$f$和$\forall a,b,c,d$,且$a<b<c<d$,有
\[f(a,c)+f(b,d)\leq f(a,d)+f(b,c)\]
即 相交区间之和 $\leq$ 包含区间之和,那么函数$f$满足四边形不等式
拿一道具体的题目来说明吧
比如:Luogu P1880 (石子合并,$NOI1995$)
这道题目中,求最小得分满足决策单调性;最大得分却不满足(打表看出来的,没有证出来...)
计算最小得分,可以通过以下dp方程解决:记$dp(i,j)$表示将第$i\text{~}j$堆合并到一起的最小得分,$w(i,j)$表示第$i\text{~}j$堆的石子总数
则有$dp(i,j)=min\{dp(i,k)+dp(k+1,j)+w(i,j)\}$,其中$i<j$
一般来说,利用四边形不等式证明决策单调性的步骤大概是:
1. 证明$w(i,j)$满足四边形不等式
2. 证明$dp(i,j)$满足四边形不等式
3. 证明$dp(i,j)$满足决策单调性
1. 证明$w(i,j)$满足四边形不等式,即$w(i,j)+w(i+1,j+1)\leq w(i,j+1)+w(i+1,j)$
通过简单的求和即可证明,上述不等式恒取等号
2. 证明$dp(i,j)$满足四边形不等式,即$dp(i,j)+dp(i+1,j+1)\leq dp(i,j+1)+dp(i+1,j)$
这个我实在没证出来...听说可能可以用归纳法
3. 由$w(i,j),dp(i,j)$满足四边形不等式,推出$dp(i,j)$满足决策单调性
若记$dp(i,j)$由$s(i,j)=k$转移而来,$dp(i,j)$满足决策单调性就是指$s(i,j)$满足$s(i,j-1)\leq s(i,j)\leq s(i+1,j)$
先用反证法证明$s(i,j-1)\leq s(i,j)$
设$dp(i,j-1)$的最优转移为$x$,$dp(i,j)$的最优转移为$y$,且$y<x$,则有
\begin{align*}dp(i,j-1)&=dp_{k=x}(i,j-1)=dp(i,x)+dp(x+1,j-1)+w(i,j-1)\\ &\leq dp_{k=y}(i,j-1)=dp(i,y)+dp(y+1,j-1)+w(i,j-1)\end{align*}
\begin{align*}dp(i,j)&=dp_{k=y}(i,j)=dp(i,y)+dp(y+1,j)+w(i,j)\\ &\leq dp_{k=x}(i,j)=dp(i,x)+dp(x+1,j)+w(i,j)\end{align*}
由于$dp(i,j)$满足四边形不等式,于是有
\[dp(y+1,j-1)+dp(x+1,j)\leq dp(y+1,j)+dp(x+1,j-1)\]
对等式左右两边都加上$dp(i,x)+dp(i,y)+w(i,j-1)+w(i,j)$,得
\begin{align*}\text{左式}&=dp(i,y)+dp(y+1,j-1)+w(i,j-1)+dp(i,x)+dp(x+1,j)+w(i,j)\\ &=dp_{k=y}(i,j-1)+dp_{k=x}(i,j)\end{align*}
\begin{align*}\text{右式}&=dp(i,y)+dp(y+1,j)+w(i,j)+dp(i,x)+dp(x+1,j-1)+w(i,j-1)\\ &=dp_{k=y}(i,j)+dp_{k=x}(i,j-1)\end{align*}
于是有
\[dp_{k=y}(i,j-1)+dp_{k=x}(i,j)\leq dp_{k=y}(i,j)+dp_{k=x}(i,j-1)\]
在条件中,右式为$dp(i-1),dp(j)$的最优转移,应当比左式小,推出矛盾
于是,有$y\geq x$,即$s(i,j-1)\leq s(i,j)$
类似的,也可以用完全相同的方法反证得出$s(i,j)\leq s(i+1,j)$
(四边形不等式为$dp(i,y)+dp(i+1,x)\leq dp(i,x)+dp(i+1,y)$,左右两边都加上$dp(x+1,j)+dp(y+1,j)+w(i,j)+w(i+1,j)$)
由决策单调性,$s(i,j)$的大致情况就可以确定了
首先,$s(i,j)$是一个$n\times n$的上三角形
由于$s(i,j-1)\leq s(i,j)$,所以每一行从左到右都是单调不减的
又因为$s(i,j)\leq s(i+1,j)$,所以每一列从上到下也是单调不减的
然后考虑dp的顺序,由于$s(i,j-1)\leq s(i,j)\leq s(i+1,j)$,所以如果已知$s(i,j-1),s(i+1,j)$,那么$s(i,j)$的范围就会被限制住
所以dp的顺序应该是,外层$i$从大到小,内层$j$从小到大
这样一来可以计算整体的复杂度:
由于$s(i,j)$的范围被$s(i,j-1),s(i+1,j)$所限制,那么总的枚举次数就是$\sum_{i=1}^{n} \sum_{j=i}^{n} (s(i+1,j)-s(i,j-1))$,也就是时间复杂度
将括号内提出来,就是$\sum_{i=1}^{n} \sum_{j=i}^{n} s(i+1,j)-\sum_{i=1}^{n} \sum_{j=i}^{n} s(i,j-1)$,其中
\[\sum_{i=1}^{n}\sum_{j=1}^{n}s(i+1,j)\leq \sum_{i=2}^{n}\sum_{j=i}^{n}s(i,j)+2n^2\]
\[\sum_{i=1}^{n}\sum_{j=1}^{n}s(i,j-1)\geq \sum_{i=1}^{n-1}\sum_{j=i}^{n-1}s(i,j)\]
于是就能得到
\begin{align*}&\sum_{i=1}^{n} \sum_{j=i}^{n} s(i+1,j)-\sum_{i=1}^{n} \sum_{j=i}^{n} s(i,j-1)\\ \leq &\sum_{i=2}^{n}\sum_{j=i}^{n}s(i,j)+2n^2-\sum_{i=1}^{n-1}\sum_{j=i}^{n-1}s(i,j)\\ \leq &\sum_{i=1}^{n} s(i,n)+2n^2\\ \leq &\ 3n^2\end{align*}
所以这种方法的时间复杂度为$O(n^2)$
这里就不写环状的了,反正只是把$a_i$再复制一份而已
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=1005; const int INF=1<<30; int n; int a[N],pre[N]; int s[N][N]; int dp[N][N]; int main() { // freopen("input.txt","r",stdin); // freopen("my.txt","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),pre[i]=pre[i-1]+a[i]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dp[i][j]=INF; for(int i=1;i<=n;i++) s[i][i]=i,dp[i][i]=0; for(int i=n-1;i>=1;i--) for(int j=i+1;j<=n;j++) for(int k=s[i][j-1];k<=s[i+1][j];k++) { int val=dp[i][k]+dp[k+1][j]+pre[j]-pre[i-1]; if(val<dp[i][j]) { s[i][j]=k; dp[i][j]=val; } } printf("%d\n",dp[1][n]); return 0; }