zoukankan      html  css  js  c++  java
  • 【dp】一题 决策单调性优化dp 斜率优化

    luoguP3515

    已知一个长度为n的序列a1,a2,...,an。
    对于每个1<=i<=n,找到最小的非负整数p满足:
    对于任意的j, (a_j)<=(a_i)+p- (sqrt{|i-j|})
    n<=5*(10^5)

    考虑j<i的方面
    则需满足对j<i a[j]<=a[i]+p-(sqrt{i-j}) , 即:a[j]+(sqrt{i-j}) <=a[i]+p
    设g是决策点 即 a[g]+(sqrt{i-g})<=a[i]+p这个g是求出(ans_p)的那个g
    所以 对于任意正整数k 有 a[g-k]+(sqrt{i-(g-k)})<=a[g]+(sqrt{i-g})
    所以:
    那么对于 询问的点i+1
    有: a[g-k]+(sqrt{i+1-(g-k)})<a[g]+(sqrt{i+1-g}) 【1】
    因为: (sqrt{i+1-(g-k)})-(sqrt(i-(g-k)))<(sqrt{i+1-g})-(sqrt{i-g})
    因为: 对于sqrt函数,数值越大 斜率越小,即是 数值越大 因变量+1增加的函数值越小

    对于【1】有结论:i点的 所有g-k 均不是i+1的决策点 (因为‘<’,所以肯定在i+1时 g点比g-k优)
    所以在j<i的条件下 对于i+1的决策点的位置 总是在i的决策点位置之后

    对于j>i同理。
    在这种(mathbf{决策单调性})情况下,可以二分+dp。

    #include<bits/stdc++.h>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int mod=1e9+7;
    const int maxn=5e5+50;
    
    //决策单调性优化dp 斜率优化
    
    int a[maxn];
    double p[maxn][2];
    inline void solve(int l,int r,int L,int R,bool ju)
    {
        if(l>r)return;
        int mid=(l+r)>>1,id=mid;
        for(int i=L;i<=min(mid,R);i++)
        {
            if(a[i]>1.0*a[mid]+1.0*p[mid][ju]-sqrt(abs(mid-i)))
            {
                p[mid][ju]=1.0*a[i]-1.0*a[mid]+sqrt(abs(mid-i));
                id=i;
            }
        }
        solve(l,mid-1,L,id,ju);solve(mid+1,r,id,R,ju);
    }
    
    
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        solve(1,n,1,n,0);
        for(int i=1;i<=n/2;i++)swap(a[i],a[n+1-i]);
        solve(1,n,1,n,1);
        for(int i=1;i<=n;i++)
            printf("%.0f
    ",ceil(max(p[n-i+1][1],p[i][0])));
    }
    
  • 相关阅读:
    荷兰国旗问题
    读取文件中数据到数组
    从五个球中选出3个枚举的简单运用
    搜索算法总结
    匿名对象
    欧几里得距离C++代码实现
    用递归法吧字符串S倒序
    利用系统来完成十进制,十六进制,八进制的转换
    DBHelper 使用的是存储过程
    DBHelper的一个小例子
  • 原文地址:https://www.cnblogs.com/kkkek/p/11997355.html
Copyright © 2011-2022 走看看