# 洛谷4072 SDOI2016征途 （斜率优化+dp）

$v\times m^2 = m\times \sum x^2 - 2 \times sum \times sum +sum*sum$

$$dp[i][p]=min(dp[j][p-1]+(s[i]-s[j]^2))$$

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk make_pair
#define ll long long
using namespace std;
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 3010;
struct Point{
int x,y;
};
ll chacheng(Point x,Point y)
{
ll xx = x.x;
ll yy = x.y;
ll xxx = y.x;
ll yyy = y.y;
return xx*yyy-xxx*yy;
}
struct Node{
Point q[maxn];
bool count(Point i,Point j,Point k)
{
Point x,y;
x.x=k.x-i.x;
x.y=k.y-i.y;
y.x=k.x-j.x;
y.y=k.y-j.y;
if (chacheng(x,y)<=0ll) return true;
return false;
}
void push(Point x)
{
q[++tail]=x;
}
void pop(int lim)
{
}
};
Node q[maxn];
int sum[maxn];
int n,m;
int dp[maxn][maxn];
int main()
{
for (int i=1;i<=n;i++) sum[i]+=sum[i-1];
for (int i=0;i<=n;i++) q[i].push((Point){0,0});
for (int i=1;i<=n;i++)
{
for (int j=1;j<=min(i,m);j++)
{
q[j-1].pop(2*sum[i]);