zoukankan      html  css  js  c++  java
  • 决策单调性

    决策单调性:状态转移的最优决策点单调递增

    可以用二分栈或者分治来实现

    二分栈中存有三元组((l,r,pos))(l)代表决策的作用起点,(r)代表决策的作用终点,(pos)是决策点的位置

    若当前状态(i)已经不在栈头决策点的范围内,就弹出栈头

    若位置为(i)的决策优于栈尾的决策,才进行下一步操作,来更新决策

    若新决策点的作用范围覆盖了旧决策点,就弹出栈尾

    若栈空了,就直接加入新决策点,说明其当前是最优的,否则就通过在旧决策点的范围内二分,来确定旧决策点的终点和新决策的的起点

    时间复杂度(O(n log n))

    诗人小G(f_i=minlimits_{j=0}^{i-1} f_j+|s_i-s_j-L-1|^P)

    (code:)

    ld calc(int i,int j)
    {
        return f[j]+qp((ld)abs(s[i]-s[j]-l-1),p);
    }
    int find(node t,int x)
    {
        int l=t.l,r=t.r,pos=t.pos,ans=t.r+1;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(calc(mid,x)<=calc(mid,pos)) r=mid-1,ans=mid;
            else l=mid+1;
        }
        return ans;
    }
    
    ......
    
    q[h=t=1]=(node){1,n,0};
    for(int i=1;i<=n;++i)
    {
        if(h<=t&&q[h].r<i) h++;
        f[i]=calc(i,q[h].pos),pre[i]=q[h].pos;
        if(calc(n,i)<=calc(n,q[t].pos))
        {
            while(h<=t&&calc(q[t].l,i)<=calc(q[t].l,q[t].pos)) t--;
            if(h>t) q[++t]=(node){i,n,i};
            else
            {
                int x=find(q[t],i);
                q[t].r=x-1;
                q[++t]=(node){x,n,i};
            }
        }
    }
    

    Lightning Conductor(f_i=maxlimits_{j=1}^{i-1} a_j-a_i+sqrt{|i-j|})

    二分栈写法

    (code:)

    struct node
    {
        int l,r,pos;
    }q[maxn];
    double calc(int i,int j)
    {
        return a[j]-a[i]+sqrt(i-j);
    }
    int find(node t,int x)
    {
        int l=t.l,r=t.r,pos=t.pos,ans=t.r+1;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(calc(mid,x)>=calc(mid,pos)) r=mid-1,ans=mid;
            else l=mid+1;
        }
        return ans;
    }
    void dp(double *f)
    {
        q[h=t=1]=(node){1,n,0};
        for(int i=1;i<=n;++i)
        {
            if(h<=t&&q[h].r<i) h++;
            f[i]=calc(i,q[h].pos);
            if(calc(n,i)>=calc(n,q[t].pos))
            {
                while(h<=t&&calc(q[t].l,i)>=calc(q[t].l,q[t].pos)) t--;
                if(h>t) q[++t]=(node){i,n,i};
                else
                {
                    int x=find(q[t],i);
                    q[t].r=x-1;
                    q[++t]=(node){x,n,i};
                }
            }
        }
    }
    

    分治写法

    (code:)

    ld calc(int i,int j)
    {
        return (ld)a[j]+(ld)sqrt((ld)(i-j));
    }
    void solve(int l,int r,int L,int R,ld *f)
    {
        int x=0,mid=(l+r)>>1;
        for(int i=L;i<=min(mid,R);++i)
        {
            ld now=calc(mid,i);
            if(now>f[mid]) f[mid]=now,x=i;
        }
        f[mid]-=a[mid];
        if(l<mid) solve(l,mid-1,L,x,f);
        if(r>mid) solve(mid+1,r,x,R,f);
    }
    
  • 相关阅读:
    20210304. 3. 通讯协议及事件处理机制
    20210304. 2. 数据类型与底层数据结构
    20210304. 1. 缓存原理 & 设计
    20210304. 0.3. Redis Cluster 搭建
    20210304. 0.2. Redis 哨兵模式搭建
    20210304. 0.1. Redis 安装
    20210208. Neo4j
    20210207. MongoDB
    20210203 8. 运维和第三方工具
    Global Brain Dynamics Embed the Motor Command Sequence of Caenorhabditis elegans
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229791.html
Copyright © 2011-2022 走看看