zoukankan      html  css  js  c++  java
  • 动态规划的斜率优化

    如题,动态规划的斜率优化

    给出如下一个状态转移方程:

      f[i]=max{x[j]*x[i]-2*f[j]}

      (我们假设x[i]单调增——她也许就是一个正整数列的前缀和)

    我们需要一种基于该转移的快速求解f[i]的方法

    观察发现:

    f[i]的取值与x[j],x[i],f[j]有关;

    由于,对于一个f[i],x[i]的取值已然却定;

    于是答案的大小取决于x[j]与f[j],换言之,取决于对j的决策对答案的贡献;

      (这不废话么)

    一个挺好的想法是枚举j,找出max;

      (慢得要死了)

    一个挺好的想法是将f[i]看为函数值;

    一个空空如也的坐标系

    一个空空如也的坐标系

    那么x[j],x[i],f[j]三项中得有一个为自变量;

    。。。。。。。。。。。。

    (博主企图解释为什么取x[i]为自变量,然后放弃了)

    总之取x[i]为自变量,可以把式子化为直线方程;

    看出 :

    k:x[j];

    b:-2*f[j];

    于是,f[i]看做x=x[i]时的函数值;

    于是我们画出f[i]=x[j]*x[i]-2*f[j]在不取MAX的可能的情况(因为j的不唯一,而存在多条直线)

    关注竖线与斜线的交点

    竖线表现x[i]的取值;

    于是观察下函数:

    f[i]=max{x[j]*x[i]-2*f[j]}

    (多了个max)

    当我们的j有很多选项时;

    意味着有很多直线存在;

    但max的存在意味着我们的函数只看处于最上面的一段直线

    咦,半平面交哟

    黄线看做函数的真正图像;

    恩,一个半平面交,但先不考虑这个;

    由于,x[]单增;

    即k,和自变量单增;

    所以直线们本来就是按越来越邪的顺序加入队列的

    由于x[i]的递增,对f[i]贡献的线也理应越来越邪(即x小时,k小的线还能占点b的优势,随x的增加,b的优势就消失了)
    于是维护单调队列,当队首这个斜率的直线不如下一条优时,她就失去意义了,该出队了,因为之后的x[]只会越来越大,她与大斜率之间的差距只会越来越大。

    于是取现在的队首信息构成f[i]的答案

    还有一点注意的;

    即,队尾的出队操作;

    我们需要用队尾的出队操作维护一个半平面交;

    方法是如果队尾前1个位置的直线与要加入队列的直线的交点在队尾直线之上,则队尾出队,重复多次直至不符合条件;

    为什么维护平面交?

    可以看出,当出现上图、也是上文中提到的情况时;

    紫线连函数的一部分都不是,当然贡献不了答案了

    换言之,维护半平面交即是维护函数图像的过程;

    (也可以说函数图像具有半平面交的性质)

     这个性质的作用:

    对,这是上文的句子;

    但她本身有些欠考量;

    这句话成立的前提条件,是维护了半平面交;也就是使上图中的紫线不在队列里;

    不然紫线会因为自己的弱小,衬托出要选小斜率直线的假象;

    友情提示:加黑字体(不含本句)即是具体要做的操作;

  • 相关阅读:
    布局重用 include merge ViewStub
    AS 常用插件 MD
    AS 2.0新功能 Instant Run
    AS .ignore插件 忽略文件
    AS Gradle构建工具与Android plugin插件【大全】
    如何开通www国际域名个人网站
    倒计时实现方案总结 Timer Handler
    AS 进行单元测试
    RxJava 设计理念 观察者模式 Observable lambdas MD
    retrofit okhttp RxJava bk Gson Lambda 综合示例【配置】
  • 原文地址:https://www.cnblogs.com/nietzsche-oier/p/6613636.html
Copyright © 2011-2022 走看看