[ SDOI 2016 ] 征途

题目

Luogu
LOJ
Acwing

思路

001.png 002.png 003.png

代码

#include <iostream>
#include <cstring>
#define int long long
using namespace std;
const int N = 3010;
int n, m, f[N][N], s[N], q[N];
int K(int a, int b, int j) { 
    int y1 = f[a][j - 1] + s[a] * s[a], x1 = s[a];
    int y2 = f[b][j - 1] + s[b] * s[b], x2 = s[b];
    return (y1 - y2) / (x1 - x2);
}
signed main() {
    cin >> n >> m;
    for (int i = 1, t; i <= n; i++)
        cin >> t, s[i] = s[i - 1] + t;
    for (int i = 1; i <= n; i++) f[i][1] = s[i] * s[i];
    for (int j = 2; j <= m; j++) {
        int hh = 0, tt = -1;
        for (int i = 1; i <= n; i++) {
            while (hh + 1 <= tt && K(q[hh], q[hh + 1], j) < 2 * s[i]) hh++;
            f[i][j] = f[q[hh]][j - 1] + (s[i] - s[q[hh]]) * (s[i] - s[q[hh]]);
            while (hh + 1 <= tt && K(q[tt - 1], q[tt], j) > K(q[tt], i, j)) tt--;
            q[++tt] = i;
        }
    }
    cout << f[n][m] * m - s[n] * s[n] << endl;
    return 0;
}
posted @ 2021-06-17 16:13  Protein_lzl  阅读(41)  评论(0编辑  收藏  举报