解法:
一开始不会做,看到标签说是贪心加二分忽然就会了,二分是分的是人口最多居住点的人口,检查人口最多的居住点人口为mid是否可行。贪心是如果从左往右循环就尽量把人口往左迁移,如果从右往左循环就尽量把人口往右迁移。
- 二分 + 贪心
1053 居民迁移 AC G++ 201ms 7MB #include "bits/stdc++.h" using namespace std; typedef long long LL; typedef pair<int, int> PII; const int MAXN = 100005; PII arr[MAXN]; int t, n, m; bool check(int mid) { int k = 0, id = 1; for (int i = 1; i <= n; i++) { // 第i号居住点的居民已经无法迁移到第id号居住点的情况 while (arr[i].first - arr[id].first > m) { // 让第i号居住点的居民迁移到下一个居住点,并初始化第id + 1号居住点的人口为0; id++; k = 0; } k += arr[i].second; // 因为每个居住点最多住mid人,当k大于mid时,剩下的居民要去下一个居住点 while (k > mid) { k -= mid; id++; } // 前者表示越出,无第id号居住点;后者表示第i号点的居民无法迁移到第id号点,但是前面的点都满员了; if (id > n || arr[id].first - arr[i].first > m) { return false; } } return true; } int main() { scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d%d", &arr[i].first, &arr[i].second); } sort(arr + 1, arr + 1 + n); int l = 1, r = 1e9; while (l < r - 1) { int mid = l + r >> 1; if (check(mid)) { r = mid; } else { l = mid; } } printf("%d\n", r); } return 0; }
原文地址:https://www.cnblogs.com/Angel-Demon/p/10459880.html
时间: 2024-11-10 13:53:58