1 条题解

  • 0
    @ 2026-3-24 9:49:49

    文字教学

    这道题的核心是枚举排列+前缀和优化。因为要把题目分成三段分给三个人,共有6种全排列方式,我们需要计算每种方式的最小总和。

    1. 前缀和预处理:先算出每个成员前i道题的难度和,方便快速算任意区间的和。
    2. 排列枚举:三个人分配三段的顺序有6种可能,逐个计算。
    3. 公式整理+前缀最小值:对固定排列,把总和公式拆成可维护的部分,用前缀最小值数组快速找最优解,把时间复杂度降到O(n)。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N = 150005;
    
    ll s[4][N];
    int n;
    
    ll calc(int p1, int p2, int p3) {
        ll res = 1e18;
        ll mn = 1e18;
        for (int j = 2; j <= n-1; ++j) {
            int i = j-1;
            ll v1 = s[p1][i] - s[p2][i];
            if (v1 < mn) mn = v1;
            ll v2 = s[p2][j] - s[p3][j];
            ll tot = s[p3][n] + mn + v2;
            if (tot < res) res = tot;
        }
        return res;
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n;
        for (int p = 1; p <= 3; ++p) {
            s[p][0] = 0;
            for (int i = 1; i <= n; ++i) {
                int x;
                cin >> x;
                s[p][i] = s[p][i-1] + x;
            }
        }
        ll ans = 1e18;
        ans = min(ans, calc(1,2,3));
        ans = min(ans, calc(1,3,2));
        ans = min(ans, calc(2,1,3));
        ans = min(ans, calc(2,3,1));
        ans = min(ans, calc(3,1,2));
        ans = min(ans, calc(3,2,1));
        cout << ans << endl;
        return 0;
    }
    
    • 1

    信息

    ID
    6945
    时间
    1000ms
    内存
    64MiB
    难度
    5
    标签
    (无)
    递交数
    2
    已通过
    2
    上传者