Print Article HDU - 3507 斜率dp

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e5+10;
int n,m,c;
int q[N];
ll dp[N];
ll sum[N];
ll get_y(int j,int k)
{
    return dp[j]+sum[j]*sum[j]-dp[k]-sum[k]*sum[k];
}
ll get_x(int j,int k)
{
    return sum[j]-sum[k];
}
int main()
{
    while(cin>>n>>m)
    {
        sum[0]=0;
        for(int i=1;i<=n;i++)
        {
            cin>>c;
            sum[i]=sum[i-1]+c;
        }
        int l=0,r=0;
        dp[0]=q[0]=0;
        for(int i=1;i<=n;i++)
        {
            while(l<r && (get_y(q[l+1],q[l]))<=get_x(q[l+1],q[l])*sum[i]*2)
                l++;
            int j=q[l];
            dp[i] = dp[j]+(sum[i]-sum[j])*(sum[i]-sum[j])+m;
            while(l<r && get_y(i,q[r])*get_x(q[r],q[r-1]) <= get_y(q[r],q[r-1])*get_x(i,q[r]) )
                r--;
            q[++r]=i;  
        }
        cout<<dp[n]<<endl;
    }
}

猜你喜欢

转载自www.cnblogs.com/QingyuYYYYY/p/12512876.html
今日推荐