1 条题解

  • 1
    @ 2026-9-25 16:17:34
    #include <algorithm>
    #include <functional>
    #include <iostream>
    #include <limits>
    #include <vector>
    
    using namespace std;
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
    
        int m, n;
        if (!(cin >> m >> n)) return 0;
        vector<long long> x(m + 1), prefix(m + 1);
        for (int i = 2; i <= m; ++i) {
            long long d;
            cin >> d;
            x[i] = x[i - 1] + d;
        }
        for (int i = 1; i <= m; ++i) prefix[i] = prefix[i - 1] + x[i];
    
        auto cost = [&](int l, int r) {
            int mid = (l + r) / 2;
            return x[mid] * (mid - l + 1LL) - (prefix[mid] - prefix[l - 1])
                 + (prefix[r] - prefix[mid]) - x[mid] * (r - mid);
        };
    
        const long long inf = numeric_limits<long long>::max() / 4;
        vector<long long> previous(m + 1, inf), current(m + 1, inf);
        previous[0] = 0;
        for (int schools = 1; schools <= n; ++schools) {
            fill(current.begin(), current.end(), inf);
            function<void(int, int, int, int)> solve = [&](int left, int right, int opt_left, int opt_right) {
                if (left > right) return;
                int mid = (left + right) / 2;
                long long best = inf;
                int best_split = opt_left;
                int last = min(mid - 1, opt_right);
                for (int split = opt_left; split <= last; ++split) {
                    long long candidate = previous[split] + cost(split + 1, mid);
                    if (candidate < best) {
                        best = candidate;
                        best_split = split;
                    }
                }
                current[mid] = best;
                solve(left, mid - 1, opt_left, best_split);
                solve(mid + 1, right, best_split, opt_right);
            };
            solve(schools, m, schools - 1, m - 1);
            previous.swap(current);
        }
    
        cout << previous[m] << '\n';
        return 0;
    }
    
    
    • 1

    信息

    ID
    1267
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    6
    已通过
    5
    上传者