斜率优化 hdu3480 pku3709 pku1180 pku2180

 斜率优化是DP优化的一种,假设状态转移方程为dp[i]=min or max (dp[k]+w[i,k]),我们假设取其中两个解k1,k2(不妨设k1<k2),然后得到dp[k1]+w[i,k1]-(dp[k2]+w[i,k2])这个表达式,不妨设结果想取最小值的话,那么上面那个表达式<0就说明k1比k2优。接着经过将左边的一些对i有关的量移到小于号右边,然后就会发现右边的式子在k1<k2时对i具有单调性(如果单调递增的话,i就从1求到n,如果递减,i就从n求到1,状态转移方程变一下)。若此时k2比k1优,那么当求后面的i时,k2一定会比k1优的(因为有单调性)。所以如果我们求dp[i]时的最佳值为kk,那么取下一个i的最优值时,kk前删除的就不用考虑了。

      但是对i的单调性是建立在k1<k2的基础上的,所以如果问题比较极端的话,每次都是最小的最佳,那么将一点改善都没有,所以我们还要寻求别的改善方法。对上面移项后的式子,把右边除i后的项全部除到左边(此时注意符号的变化)。把此时左边的所有项记为G(k1,k2),如果k1<k2且G(k1,k2)<f[i](这是假设上面符号没变,符号变了后可以自己推下)时,k1比k2优.如果存在k1<k2<k3,使得G(k1,k2)<=G(k2,k3)时,k2永远不会是最佳的。因为当G(k1,k2)<=f[ii]时,k1会比k2,当G(k1,k2)>f[ii]时,G(k2,k3)也会>f[ii],此时k3会比k2优.所以此时可以把k2去掉,去掉后G(k1,k2)会保持单调递减,所以把此时的f[ii]插入到G(k1,k2)中,前面的G(k1,k2)都会>=f[ii],此时k2会比k1优,后面的都是k1比k2优,所以插入点的那个位置就可以知道最优的kk.具体的实现用两端都能出的队列即可完成。因为每个点进一次出一次队列,所以时间复杂度为O(n)。下面以hdu3480详细解释一下过程.

      hdu3480求将一个大集合分为m个小集合,使每个集合最大元素减最小元素平方和最小.

也可用四边形不等式。排序后,状态转移方程为dp[i][j]=min(dp[k][j-1]+(a[i]-a[k+1])^2),然后k1<k2并且满足dp[k2][j-1]-dp[k1][j-1]+a[k2+1]*a[k2+1]-a[k1+1]*a[k1+1]<2*a[i]*(a[k2+1]-a[k1+1])时,k2会比k1优,所以把k1去掉。把右边的2*(a[k2+1]-a[k1+1])除到左边去(此时注意除的数的正负),然后把整体定义为一个函数G(k1,k2),如果G(k1,k2)<a[i]时,k2会比k1优。如果现在存在k1<k2<k3&&G(k2,k3)<G(k1,k2)时,那么k2是多余的,它永远也不会取到最优值(分别对G(k2,k3)<?a[i]讨论)。所以直接把k2去掉.


  斜率优化与四边形不等式的区别在于四边形不等式满足k续单调,而斜率只是保证取最优值的k单调。

你可能感兴趣的:(斜率优化 hdu3480 pku3709 pku1180 pku2180)