码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 3507 Print Article(斜率优化)

时间:2018-04-01 18:47:48      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:bug   lowbit   span   abs   def   owb   价值   turn   scan   

题意:给你一串数,然后有一个价值计算公式,每次只能连续输出一段,问输出所有数的总价值最小是多少

思路:斜率优化,但我不知道为什么写成slop就不对,可怜我的斜率优化板子,又要该了,其他没什么,简单的推一下是下凸包,没什么其他的了

代码:

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <vector>
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#define zero(a) fabs(a)<eps
#define max( x, y )  ( ((x) > (y)) ? (x) : (y) )
#define min( x, y )  ( ((x) < (y)) ? (x) : (y) )
#define lowbit(x) (x&(-x))
#define debug(a) cerr<<#a<<"=="<<a<<endl
typedef long long ll;
const double pi=acos(-1.0);
const double eps=1e-8;
const int inf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;
using namespace std;


const int maxn=500000+7;

int a[maxn],dp[maxn],pre[maxn];
int que[maxn],l,r;

int getUP(int j,int k)
{
    return dp[j]+pre[j]*pre[j]-(dp[k]+pre[k]*pre[k]);
}
int getDOWN(int j,int  k)
{
    return 2*(pre[j]-pre[k]);
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        l=1,r=0;
        pre[0]=0;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),pre[i]=pre[i-1]+a[i];
        dp[0]=0;
        que[++r]=0;
        for(int i=1;i<=n;i++){
            while(l<r&&getUP(que[l+1],que[l])<=getDOWN(que[l+1],que[l])*pre[i])l++;
            int j=que[l];
            dp[i]=dp[j]+(pre[i]-pre[j])*(pre[i]-pre[j])+m;
            while(l<r&&getUP(que[r],que[r-1])*getDOWN(i,que[r])>=getUP(i,que[r])*getDOWN(que[r],que[r-1])) r--;
            que[++r]=i;
        }
        printf("%d\n",dp[n]);
    }
    return 0;
}

 

hdu 3507 Print Article(斜率优化)

标签:bug   lowbit   span   abs   def   owb   价值   turn   scan   

原文地址:https://www.cnblogs.com/lalalatianlalu/p/8687533.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!