zoukankan      html  css  js  c++  java
  • 题解【POJ2376】Cleaning Shifts

    题面

    题意简述:

    (m) 个区间,每一段区间为 ([L_i,R_i]),现在有一个长度为 (n) 的线段,问最少选择多少个区间,才能够覆盖整个线段。

    ( exttt{Data Range: }1leq m leq 2.5 imes 10^4, 1leq n leq 10^6)

    (dp_i) 表示只选择 (i) 左边的区间,覆盖区间 ([1,i]) 最少选择多少个区间。

    假设当前区间左端点为 (l),右端点为 (r),那么状态的转移就是 (dp_r = minlimits_{l-1leq j < r}{dp_j} + 1)

    然后可以使用一个单点修改、区间查询的线段树维护 (dp) 值。

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    const int N = 25003, M = 1000003, INF = 0x3f3f3f3f;
    
    int n, m;
    struct Node
    {
        int l, r;
    } a[N];
    int tr[M << 2];
    int f[M];
    
    inline bool cmp(Node x, Node y) 
    {
        if (x.r != y.r) return x.r < y.r;
        return x.l < y.l;
    }
    
    inline int ls(int p) {return p << 1;}
    inline int rs(int p) {return p << 1 | 1;}
    
    inline void pushup(int p) {tr[p] = min(tr[ls(p)], tr[rs(p)]);}
    
    void build(int l, int r, int p)
    {
        tr[p] = INF;
        if (l == r) return;
        int mid = (l + r) >> 1;
        build(l, mid, ls(p)); build(mid + 1, r, rs(p));
    }
    
    void modify(int k, int v, int l, int r, int p)
    {
        if (l == r) {tr[p] = min(tr[p], v); return;}
        int mid = (l + r) >> 1;
        if (k <= mid) modify(k, v, l, mid, ls(p));
        else modify(k, v, mid + 1, r, rs(p));
        pushup(p);
    }
    
    int getans(int ql, int qr, int l, int r, int p)
    {
        if (ql <= l && r <= qr) return tr[p];
        int mid = (l + r) >> 1;
        int res = INF;
        if (ql <= mid) res = getans(ql, qr, l, mid, ls(p));
        if (qr > mid) res = min(res, getans(ql, qr, mid + 1, r, rs(p)));
        return res;
    }
    
    int main()
    {
        scanf("%d%d", &m, &n);
        for (int i = 1; i <= m; i+=1) scanf("%d%d", &a[i].l, &a[i].r);
        build(0, n, 1);
        sort(a + 1, a + 1 + m, cmp);
        memset(f, 0x3f, sizeof f);
        f[0] = 0;
        modify(0, 0, 0, n, 1);
        for (int i = 1; i <= m; i+=1)
        {
            f[a[i].r] = min(f[a[i].r], getans(a[i].l - 1, a[i].r - 1, 0, n, 1) + 1);
            modify(a[i].r, f[a[i].r], 0, n, 1);
        }
        if (f[n] == INF) f[n] = -1;
        printf("%d
    ", f[n]);
        return 0;
    }
    
  • 相关阅读:
    非常奇怪的VS2005无法调试的问题
    自已写的“动易PowerEasy2006暴库工具”
    用VBA去除Excel工作表保护密码
    mapgis同arcmap之间的数据转换, 投影变换,误差校正,坐标,基础资料,教程的相关信息的汇集
    HDU You Are the One (dp)
    HDU4291 A Short problem
    Mondriaan's Dream(poj2411)
    HDU 4277 USACO ORZ
    求欧拉回路的路径(usaco3.3Riding the Fences)
    poj2923 (状态压缩01背包)
  • 原文地址:https://www.cnblogs.com/xsl19/p/12772302.html
Copyright © 2011-2022 走看看