【dp】一题 决策单调性优化dp 斜率优化

爷,独闯天下 提交于 2019-12-06 20:16:40

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\n",ceil(max(p[n-i+1][1],p[i][0])));
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!