1 条题解
-
0
贪心
下面所用字母为题面中代表含义。
车提供的贡献为:
简单分析这个式子
- 当 时, 对贡献无影响
- 当 时,随着 的增大贡献单调增加。
- 当 时,随着 的增大贡献单调减少。
因为单调性所以车应该尽可能的靠近两个端点。
结论1: 车辆的起始位置在两端
是到A市(0点)的距离,这意味着如果某辆车去A市次数更多,那么这辆车在货车的相对顺序中应该更靠前。
结论2: 车的相对顺序为:由 的值从大到小排列。
综合两个结论,枚举车可能停靠的所有位置,求出最小值答案。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<LL, LL> PII; #define x first #define y second const int N = 2e5 + 10, M = 60; int n, m, x; PII site[N], car[N]; bool cmp(PII a, PII b) { return a.x - a.y > b.x - b.y; } LL cal(int i, int j) // 位置下标,车下标。计算对答案的贡献 { return car[j].x * site[i].x * 2 + car[j].y * (x - site[i].x) * 2; } int main() { cin >> n >> m >> x; for(int i = 1; i <= n; i ++) cin >> site[i].x >> site[i].y; for(int i = 1; i <= m; i ++) cin >> car[i].x >> car[i].y; sort(site + 1, site + 1 + n); sort(car + 1, car + 1 + m, cmp); LL ans = 0; vector<int> v(m + 1); // 保存每个车的位置 for(int i = 1, j = 1; i <= n && j <= m; i ++) //计算所有车全放前面的结果 { for(int k = 0; k < site[i].y; k ++) { ans += cal(i, j); v[j] = i; j ++; if(j > m) break; } } LL t = ans; for(int i = n, j = m; i >= 1 && j >= 1; i --) // 枚举所有车辆放置情况 { for(int k = 0; k < site[i].y; k ++) { t = t - cal(v[j], j) + cal(i, j); ans = min(ans, t); j --; if(j < 1) break; } } cout << ans << endl; }
- 1
信息
- ID
- 188
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 17
- 已通过
- 2
- 上传者