斜率优化dp

模板题,但还是不熟练,,,多练多推导吧:#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
const int maxn=100002;
int n,m,a[maxn],s[maxn],f[maxn];
void init(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
s[0]=0;
for (int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
}


int getup(int a,int b){ return (f[a]-f[b]-s[a]*s[a]+s[b]*s[b]);}


int getdown(int a,int b){return 2*(s[a]-s[b]); }


int getdp(int i,int x){ return (f[x]+m+(s[i]-s[x])*(s[i]-s[x]));}


void dp(){
int que[maxn],head=0,tail=1;
f[0]=que[0]=0; 
for (int i=1;i<=n;i++){
while (head+1<tail&&getup(que[head+1],que[head])<=s[i]*getdown(que[head+1],que[head])) head++; 
f[i]=getdp(i,que[head]);
while (head+1<tail&&
 getup(i,que[tail-1])*getdown(que[tail-1],que[tail-2])<=getup(que[tail-1],que[tail-2])*getdown(i,que[tail-1])) tail--;
que[tail++]=i;
}
}


void print(){ printf("%d",f[n]);}


int main(){
init();
dp();
print();
return 0;
}

你可能感兴趣的:(斜率优化dp)