1 条题解
-
0
文字教学
这道题的核心是枚举排列+前缀和优化。因为要把题目分成三段分给三个人,共有6种全排列方式,我们需要计算每种方式的最小总和。
- 前缀和预处理:先算出每个成员前i道题的难度和,方便快速算任意区间的和。
- 排列枚举:三个人分配三段的顺序有6种可能,逐个计算。
- 公式整理+前缀最小值:对固定排列,把总和公式拆成可维护的部分,用前缀最小值数组快速找最优解,把时间复杂度降到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
- 上传者
京公网安备 11011102002149号