1 条题解
-
1
#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; }
信息
- ID
- 1267
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 6
- 已通过
- 5
- 上传者