[关闭]
@ZCDHJ 2019-07-31T04:00:33.000000Z 字数 1059 阅读 377

Lugou2900 土地征用

未分类


考虑对于 的土地如果有 的土地满足 将不会对答案产生任何贡献。所以将这些土地删去。最后留下的土地序列按 排序后一定 递增, 递减。这样子每次最优d的决策一定是连续的区间,方程为 ,斜率优化即可。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. typedef long long LL;
  5. #define int LL
  6. const int MAXN = 5e4;
  7. int n, tail, l, r;
  8. int dp[MAXN | 1], q[MAXN | 1];
  9. struct Land {
  10. int a, b;
  11. friend bool operator< (const Land &lhs, const Land &rhs) {
  12. return (lhs.a < rhs.a) || (lhs.a == rhs.a && lhs.b > rhs.b);
  13. }
  14. } a[MAXN | 1], s[MAXN | 1];
  15. inline int read() {
  16. register int x = 0;
  17. register char ch = getchar();
  18. while (!isdigit(ch)) ch = getchar();
  19. while (isdigit(ch)) {
  20. x = x * 10 + ch - '0';
  21. ch = getchar();
  22. }
  23. return x;
  24. }
  25. inline double slope(int x, int y) {
  26. return 1.0 * (dp[y] - dp[x]) / (s[x + 1].b - s[y + 1].b);
  27. }
  28. signed main() {
  29. n = read();
  30. for (int i = 1; i <= n; ++i) {
  31. a[i].a = read();
  32. a[i].b = read();
  33. }
  34. std::sort(a + 1, a + 1 + n);
  35. for (int i = 1; i <= n; ++i) {
  36. while (tail > 0 && s[tail].b <= a[i].b) --tail;
  37. s[++tail] = a[i];
  38. }
  39. l = 1;
  40. r = 1;
  41. for (int i = 1; i <= tail; ++i) {
  42. while (l < r && slope(q[l], q[l + 1]) <= s[i].a) ++l;
  43. int j = q[l];
  44. dp[i] = dp[j] + s[i].a * s[j + 1].b;
  45. while (l < r && slope(q[r - 1], q[r]) >= slope(q[r], i)) --r;
  46. q[++r] = i;
  47. }
  48. printf("%lld\n", dp[tail]);
  49. return 0;
  50. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注