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个位置的直线与要加入队列的直线的交点在队尾直线之上,则队尾出队,重复多次直至不符合条件;

    为什么维护平面交?

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

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

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

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

     这个性质的作用:

    对,这是上文的句子;

    但她本身有些欠考量;

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

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

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

  • 相关阅读:
    [bzoj4721][noip2016]蚯蚓
    [bzoj1112][POI2008]砖块KLO
    [bzoj3196][tyvj1728]普通平衡树
    [bzoj1596][Usaco2008 Jan]电话网络
    [bzoj3371][poj2009][Usaco2004 Mar]Moo University
    [bzoj2208][Jsoi2010]连通数
    郑捷《机器学习算法原理与编程实践》学习笔记(第四章 推荐系统原理)(二)kmeans
    郑捷《机器学习算法原理与编程实践》学习笔记(第四章 推荐系统原理)(一)推荐系统概述
    Python_sklearn机器学习库学习笔记(四)decision_tree(决策树)
    C++STL学习笔记_(1)vector知识
  • 原文地址:https://www.cnblogs.com/nietzsche-oier/p/6613636.html
Copyright © 2011-2022 走看看