• POJ 1769_Minimizing maximizer


    题意:

    一系列m个1~n区间,每个区间固定对某个子区间进行排序,顺序选择若干区间,使最终覆盖所有区间。

    分析:

    computes the length of the shortest subsequence of the initial sequence of sorters still producing correct results for all possible input data

    要想明白几点:

    • 输入时最大值的位置情况不确定,但是只要求出最大值在第一个位置的最短sorter序列,其他位置的情况就均满足了。
    • 怎样删才能保证正常输出?就是最大值在删去中间几个sorter之后位置不发生改变。

    dp[j]表示最大值到达j位置所需的最少sorter个数,有两种情况:

    • 在第i1个sorter中最大值k,满足ai1k<bi1,那么在第i个sorter中最大值则被移动到bi1的位置。
    • 否则,最大值位置不发生改变,则可以省去第i1个sorter

    可以得到状态转移方程:

    dp[b[i]] = min(dp[b[i]], dp[j] + 1);  a[i]<= j < b[i]

    然后就TLE了。。。。然后就一脸懵逼.jpg


    m个sorter肯定要遍历一遍,就只能在最少次数的获取上优化了。不停的获取最少次数又不停的更新到dp[b[i]],单节点更新问题,可以用线段树优化,时间复杂度降为O(mlogn)

    代码:

    #include<cstdio>
    #define min( a, c ) (a)<(c)?(a):(c)
    const int maxn = 500005, INF = 0x3fffffff;
    int a[maxn], b[maxn], m[3*maxn];
    void build(int k, int l, int r)
    {
        m[k] = INF;
        if(l == r - 1) return;
        build(k * 2 + 1,l, (l+r)/2);
        build(k * 2 + 2, (l+r)/2, r);
    }
    void update(int a, int  x, int k, int l, int r)
    {
          m[k] = min(x, m[k]);
          if(l < r-1){
            int m = (l+r)/2;
            if(m > a) update(a, x, k * 2 + 1, l, m);
            else update(a, x, k * 2 + 2, m, r);
        }
    }
    int query(int a, int b, int k, int l, int r)
    {
        if(a >= r|| b <= l) return INF;
        else if(a <= l && r <= b) return m[k];
        else {
            int ta = query(a, b, k * 2 + 1, l, (l+r)/2);
            int tb = query(a, b, k * 2 + 2, (l + r)/2, r);
            return min(ta, tb);
        }
    }
    int main (void)
    {
        int n, _m;scanf("%d%d",&n,&_m);
        build(0, 0, n);
        update(0, 0, 0, 0, n);
        for(int i = 0; i < _m; i++) {
                scanf("%d%d",&a[i],&b[i]);
                int t = query(a[i]-1, b[i], 0, 0, n) + 1;
                update(b[i]-1, t, 0, 0, n);
        }
        printf("%d
    ",query(n-1, n, 0, 0, n));
    }
    

    选择合适的数据结构对dp进行优化,可以降低计算的复杂度。

  • 相关阅读:
    Linux 02
    Linux 01
    React 函数式组件的 Ref 和子组件访问(useImperativeHandle)
    排序算法之 Java插入排序算法
    排序算法之 Java选择排序算法
    排序算法之 Java冒泡算法
    类加载的过程---验证和准备
    类加载的过程---加载
    mysql explain 查询处理的结果详解
    springboot整合分布式缓存hazelCast
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758782.html
Copyright © 2020-2023  润新知