[关闭]
@ZCDHJ 2019-09-21T12:20:31.000000Z 字数 1554 阅读 508

HAOI2011 problem a

未分类


对于一组 可以看成表示与第 个人同分的人的区间是 。那么将一定假的情况先剔除,接下来可以将问题看成是选择若干个不相交的区间,使得区间的权值和最大。使用树状数组优化 DP 即可。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. const int MAXN = 100000;
  6. int n, a[MAXN | 1], b[MAXN | 1], dp[MAXN | 1], bit[MAXN | 1];
  7. struct Range {
  8. int l, r, res;
  9. Range() : l(0), r(0), res(0) {}
  10. Range(int _l, int _r) : l(_l), r(_r) {}
  11. friend bool operator< (const Range &lhs, const Range &rhs) {
  12. return lhs.l < rhs.l || (lhs.l == rhs.l && lhs.r < rhs.r);
  13. }
  14. } range[MAXN | 1], tm[MAXN | 1];
  15. inline bool comp(const Range &lhs, const Range &rhs) {
  16. return lhs.r < rhs.r;
  17. }
  18. inline int read() {
  19. register int x = 0;
  20. register char ch = getchar();
  21. while (!isdigit(ch)) ch = getchar();
  22. while (isdigit(ch)) {
  23. x = x * 10 + ch - '0';
  24. ch = getchar();
  25. }
  26. return x;
  27. }
  28. void modify(int x, int y) {
  29. if (x <= 0) x = 1;
  30. while (x <= n) {
  31. bit[x] = std::max(bit[x], y);
  32. x += x & (-x);
  33. }
  34. }
  35. int query(int x) {
  36. int res = 0xcfcfcfcf;
  37. // printf("res=%d\n", res);
  38. while (x > 0) {
  39. res = std::max(res, bit[x]);
  40. x -= x & (-x);
  41. }
  42. return res;
  43. }
  44. int main() {
  45. n = read();
  46. for (int i = 1; i <= n; ++i) {
  47. a[i] = read();
  48. b[i] = read();
  49. }
  50. for (int i = 1; i <= n; ++i) {
  51. range[i].l = a[i] + 1;
  52. range[i].r = n - b[i];
  53. }
  54. std::sort(range + 1, range + 1 + n);
  55. int tot = 0;
  56. for (int i = 1; i <= n; ++i) {
  57. if (range[i].l > range[i].r) continue;
  58. if (range[i].l != range[i - 1].l || range[i].r != range[i - 1].r) {
  59. tm[++tot].l = range[i].l;
  60. tm[tot].r = range[i].r;
  61. tm[tot].res = 1;
  62. } else {
  63. tm[tot].res += 1;
  64. if (tm[tot].res > tm[tot].r - tm[tot].l + 1) tm[tot].res = tm[tot].r - tm[tot].l + 1;
  65. }
  66. }
  67. std::sort(tm + 1, tm + 1 + tot, comp);
  68. memset(bit, 0xcf, sizeof(bit));
  69. dp[tm[1].r] = tm[1].res;
  70. modify(tm[1].r, tm[1].res);
  71. for (int i = 2; i <= tot; ++i) {
  72. dp[tm[i].r] = std::max(query(tm[i].l - 1), 0) + tm[i].res;
  73. modify(tm[i].r, dp[tm[i].r]);
  74. }
  75. printf("%d\n", n - query(tm[tot].r));
  76. return 0;
  77. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注