斜率优化系列——训练记录

斜率优化训练记录

前言

斜率优化一般用于优化dp的转移,借着训练斜率优化的相关问题来提升一些DP思维。选择老学长留下的专题场来练手,由于该场题数较多,以及个人不太愿意长时间进行单一专题训练,因此开此文来记录断续的训练结果和心得。

记录

题一

由一道简单入门题玩具装箱开头,题意和思路比较简单就不讲了。
代码

#include<bits/stdc++.h>
#define dd(x) cout<<#x<<" = "<<x<<" "
#define de(x) cout<<#x<<" = "<<x<<endl
#define sz(x) int(x.size())
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define All(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef priority_queue<int> BQ;
typedef priority_queue<int,vector<int>,greater<int> > SQ;
const int maxn=1e5+10,INF=0x3f3f3f3f,mod=1e9+7;
ll f[maxn],sum[maxn],a[maxn],q[maxn],h,t;
inline double K(int i,int j)
{
    double dy=a[j]*a[j]+f[j]-a[i]*a[i]-f[i],dx=a[j]-a[i];
    return dy/dx;
}
int main()
{
    int n,l;
    cin>>n>>l;
    for (int i=1;i<=n;++i)
    {
        int x;
        scanf("%d",&x);
        sum[i]=sum[i-1]+x;
        a[i]=i+1+sum[i];
    }
    a[0]=1;
    h=t=1;
    for (int i=1;i<=n;++i)
    {
        while (h<t&&K(q[h],q[h+1])<2*(sum[i]+i-l))
            h++;
        int j=q[h];
        ll tmp=i-j-1+sum[i]-sum[j]-l;
        f[i]=f[j]+tmp*tmp;
        while (h<t&&K(q[t-1],q[t])>K(q[t-1],i))
            t--;
        q[++t]=i;
    }
    cout<<f[n];
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/orangee/p/10661996.html