• HDU 6249 Alice’s Stamps


    题目链接

    题目大意:

    说有$m$个区间,要求选出不超过$k$个区间,使这些区间覆盖的长度最长,问最长长度是多少。

    题解:

    所有区间按$R$从小到大排序之后可以进行$dp$。

    $dp[i][j]$表示:拿了小于等于$i$个区间,最后一个以坐标小于等于$j$为结尾的最长覆盖长度

    假设第$x$个区间作为结尾,那么要分两种情况来考虑:

    1.可以是之前的结尾小于第$x$个区间的左端点,这种情况很好解决。

    2.也可以是之前区间的结尾在第$x$个区间内部。

    第二种情况的话:

    不允许在区间内部进行枚举点,否则时间复杂度炸了,可以发现要求的是类似于$dp[j] + i - j$格式的最大值,也就是$i$加上区间上$dp[j]-j$的最大值,因此可以用ST表计算区间最大值。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 2100;
    int T, n, m, K;
    struct X {
      int L, R;
      int x;
    }s[maxn];
    int dp[maxn][maxn];
    int t[maxn * 4];
    int rmq[maxn][15];
    
    bool cmp(const X&a, const X&b) {
      return a.R < b.R;
    }
    
    void ST(int num) {
      for (int i = 1; i <= n; i++)
        rmq[i][0] = dp[num][i] - i;
      for (int j = 1; (1 << j) <= n; j++) {
        for (int i = 1; i + (1 << j) - 1 <= n; i++) {
          rmq[i][j] = max(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
        }
      }
    }
    
    int RMQ(int l, int r) {
      int k = 0;
      while ((1 << (k + 1)) <= r - l + 1) k++;
      return max(rmq[l][k], rmq[r - (1 << k) + 1][k]);
    }
    
    int main() {
      scanf("%d", &T);
      int cas = 1;
      while(T --) {
        scanf("%d%d%d", &n, &m, &K);
        for(int i = 1; i <= m; i ++) {
          scanf("%d%d", &s[i].L, &s[i].R);
          s[i].x = s[i].R - s[i].L + 1;
        }
        sort(s + 1, s + 1 + m, cmp);
        /*
         dp[i][j], 拿了 <= i 个,最后一个以坐标 <= j 为结尾
         */
        int ans = 0;
        ST(0);
        for(int i = 1; i <= K; i ++) {
          int now = 1;
          while(now <= m && s[now].R < i) now ++;
          for(int j = i; j <= n; j ++) {
            dp[i][j] = 0;
            while(now <= m && s[now].R == j) {
              dp[i][j] = max(dp[i][j],
                                s[now].x + dp[i - 1][s[now].L - 1]);
              dp[i][j] = max(dp[i][j],
                                RMQ(s[now].L, s[now].R) + j);
              now ++;
            }
            dp[i][j] = max(dp[i][j - 1], dp[i][j]);
            ans = max(ans, dp[i][j]);
            if(ans == n) break;
          }
          if(ans == n) break;
          ST(i);
        }
        printf("Case #%d: %d
    ", cas ++, ans);
      }
      return 0;
    }
    
  • 相关阅读:
    Maven命名约定
    8.30面试
    8.28面试
    8.27面试总结
    vue引入图片之require()
    使用pxtorem时遇到PostCSS plugin postcss-pxtorem requires PostCSS 8
    vue之Missing required prop: "id"
    git首次使用
    vue中style的scoped属性
    JavaScript中的this与function中的this
  • 原文地址:https://www.cnblogs.com/zufezzt/p/8430868.html
Copyright © 2020-2023  润新知