loj2035 「SDOI2016」征途

学了斜率优化这题就能一气呵成地做出来啦qwqqwq

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int n, m, x[3005], s[3005], l, r, dp[3005][3005], que[3005];
struct Node{
    int x, y;
}nd[3005];
double getK(Node u, Node v){
    return (double)(v.y-u.y)/(v.x-u.x);
}
int main(){
    cin>>n>>m;
    for(int i=1; i<=n; i++){
        scanf("%d", &x[i]);
        s[i] = s[i-1] + x[i];
    }
    for(int i=1; i<=n; i++)
        dp[i][1] = s[i] * s[i];
    for(int j=2; j<=m; j++){
        l = r = 0;
        for(int i=1; i<=n; i++){
            while(l<r && getK(nd[que[l]], nd[que[l+1]])<2*s[i]) l++;
            dp[i][j] = dp[que[l]][j-1] + (s[i]-s[que[l]]) * (s[i]-s[que[l]]);
            nd[i] = (Node){s[i], dp[i][j-1]+s[i]*s[i]};
            while(l<r && getK(nd[que[r-1]], nd[que[r]])>=getK(nd[que[r]], nd[i]))
                r--;
            que[++r] = i;
        }
    }
    cout<<m*dp[n][m]-s[n]*s[n]<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/poorpool/p/8939999.html
今日推荐