• 原题如下:

    Minimizing maximizer
    Time Limit: 5000MS   Memory Limit: 30000K
    Total Submissions: 5104   Accepted: 2066

    Description

    The company Chris Ltd. is preparing a new sorting hardware called Maximizer. Maximizer has n inputs numbered from 1 to n. Each input represents one integer. Maximizer has one output which represents the maximum value present on Maximizer's inputs.

    Maximizer is implemented as a pipeline of sorters Sorter(i1, j1), ... , Sorter(ik, jk). Each sorter has n inputs and n outputs. Sorter(i, j) sorts values on inputs i, i+1,... , j in non-decreasing order and lets the other inputs pass through unchanged. The n-th output of the last sorter is the output of the Maximizer.

    An intern (a former ACM contestant) observed that some sorters could be excluded from the pipeline and Maximizer would still produce the correct result. What is the length of the shortest subsequence of the given sequence of sorters in the pipeline still producing correct results for all possible combinations of input values?

    Task 
    Write a program that:

    reads a description of a Maximizer, i.e. the initial sequence of sorters in the pipeline, 
    computes the length of the shortest subsequence of the initial sequence of sorters still producing correct results for all possible input data, 
    writes the result. 

    Input

    The first line of the input contains two integers n and m (2 <= n <= 50000, 1 <= m <= 500000) separated by a single space. Integer n is the number of inputs and integer m is the number of sorters in the pipeline. The initial sequence of sorters is described in the next m lines. The k-th of these lines contains the parameters of the k-th sorter: two integers ik and jk (1 <= ik < jk <= n) separated by a single space.

    Output

    The output consists of only one line containing an integer equal to the length of the shortest subsequence of the initial sequence of sorters still producing correct results for all possible data.

    Sample Input

    40 6
    20 30
    1 10
    10 20
    20 30
    15 25
    30 40

    Sample Output

    4
    

    Hint

    Huge input data, scanf is recommended.
  • 题解:首先,考虑在什么情况下可以正常工作,假设输入的第i个数是应该输出的最大值,此时在第一个满足sk≤i≤tk的Sorter的输出中,这个值被移动到了第tk个位置,接下去,在一个满足sk'≤tk≤tk'且k'>k的Sorter的输出中,这个值又被移动到了第tk'个。不断重复这样的操作,如果最后可以被移动到第n个,那么就表示Maximizer可以正常工作(实际上,就是要按照线段的输入顺序,将[1, n]从左到右依次覆盖,求所需线段个数的最小值)。因此只要i=1的情况可以正常工作,那么对于任意的i都可以正常工作。不妨假设第一个数是应该输出的最大值,考虑DP:
      dp[i][j]:=到第i个Sorter为止,最大值被移动到第j个位置所需要的最短的子序列的长度(INF表示不存在这样的序列)
      dp[0][1]=0
      dp[0][j]=INF(j>1)
      dp[i+1][j]=①dp[i][j] (ti ≠ j)
                      ②min( dp[i][j] , min{dp[i][j']|si≤j'≤ti}+1 ) (t= j)
    由于这个DP的复杂度是O(nm)的,仍然无法在规定的时间内求出答案。但是对于(ti ≠ j)时有dp[i+1][j]=dp[i][j],我们可以使用同一个数组不断对自己更新:
      dp[j]:=最大值被移动到第j个位置所需要的最短的子序列的长度。(INF表示不存在这样的序列)
    初始化:
      dp[1]=0
      dp[j]=INF(j>1)
    对于每个i,这样更新:
      dp[ti]=min(  dp[ti], min{dp[j']|si≤j'≤ti}+1 )
    这样,对于每个i都只需更新一个值就可以了,但求最小值时,最坏情况下要O(n)的时间,最后复杂度还是O(nm)。如果使用线段树来维护,就可以在O(mlogn)时间内求解了。
  • 代码:
     #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define number s-'0' using namespace std; const int INF=0x3f3f3f3f;
    const int MAX_N=;
    const int MAX_M=;
    int n,m;
    int s[MAX_M], t[MAX_M];
    int dp[MAX_N+];
    int dat[*MAX_N]; void read(int &x)
    {
    char s;
    bool flag=;
    x=;
    while (!isdigit(s=getchar()))
    (s=='-')&&(flag=true);
    for (x=number; isdigit(s=getchar());x=x*+number);
    (flag)&&(x=-x);
    } void write(int x)
    {
    if (x<)
    {
    putchar('-');
    x=-x;
    }
    if (x>) write(x/);
    putchar(x%+'');
    } void rmq_init(int k, int l, int r);
    void update(int u, int v, int k, int l, int r);
    int query(int a, int b, int k, int l, int r); int min(int x, int y)
    {
    if (x<y) return x;
    return y;
    } int main(int argc, char * argv[])
    {
    read(n);read(m);
    for (int i=; i<m; i++)
    {
    read(s[i]);read(t[i]);
    s[i]--;t[i]--;
    }
    rmq_init(, , n);
    fill(dp, dp+MAX_N, INF);
    dp[]=;
    update(, , , , n);
    for (int i=; i<m; i++)
    {
    int v=min(dp[t[i]], query(s[i], t[i]+, , , n)+);
    dp[t[i]]=v;
    update(t[i], v, , , n);
    }
    write(dp[n-]);putchar('\n');
    } void rmq_init(int k, int l, int r)
    {
    dat[k]=INF;
    if (r-l==) return;
    rmq_init(k*+, l, (l+r)/);
    rmq_init(k*+, (l+r)/, r);
    } void update(int u, int v, int k, int l, int r)
    {
    if (r-l==)
    {
    dat[k]=v;
    return;
    }
    else
    {
    int m=(l+r)/;
    if (u<m) update(u, v, k*+, l, m);
    else update(u, v, k*+, m, r);
    dat[k]=min(dat[k*+], dat[k*+]);
    }
    } int query(int a, int b, int k, int l, int r)
    {
    if (r<=a || b<=l) return INF;
    if (a<=l && r<=b) return dat[k];
    else
    {
    int m=(l+r)/;
    int vl=query(a, b, k*+, l, m);
    int vr=query(a, b, k*+, m, r);
    return min(vl, vr);
    }
    }

Minimizing maximizer(POJ 1769)的更多相关文章

  1. POJ 1769 Minimizing maximizer(DP+zkw线段树)

    [题目链接] http://poj.org/problem?id=1769 [题目大意] 给出一些排序器,能够将区间li到ri进行排序,排序器按一定顺序摆放 问在排序器顺序不变的情况下,一定能够将最大 ...

  2. poj 1769 Minimizing maximizer 线段树维护dp

    题目链接 给出m个区间, 按区间给出的顺序, 求出覆盖$ [1, n] $ 至少需要多少个区间. 如果先给出[10, 20], 在给出[1, 10], 那么相当于[10, 20]这一段没有被覆盖. 令 ...

  3. POJ.1769.Minimizing maximizer(线段树 DP)

    题目链接 /* 题意:有m个区间,问最少要多少个区间能覆盖[1,n] 注:区间要按原区间的顺序,不能用排序贪心做 设dp[i]表示最右端端点为i时的最小值 dp[e[i]]=min{dp[s[i]]~ ...

  4. POJ 1769 Minimizing maximizer (线段树优化dp)

    dp[i = 前i中sorter][j = 将min移动到j位置] = 最短的sorter序列. 对于sorteri只会更新它右边端点r的位置,因此可以把数组改成一维的,dp[r] = min(dp[ ...

  5. POJ1769 Minimizing maximizer(DP + 线段树)

    题目大概就是要,给一个由若干区间[Si,Ti]组成的序列,求最小长度的子序列,使这个子序列覆盖1到n这n个点. dp[i]表示从第0个到第i个区间且使用第i个区间,覆盖1到Ti所需的最少长度 对于Si ...

  6. uva 1322 Minimizing Maximizer

    题意: 有n个数,m个排序器,每个排序器可以把区间ai到bi的数从小到大排序.这m个排序器的输出就是m个排序之后的第n个数. 现在发现有些排序器是多余的.问至少需要多少个排序器可以使得输出不变.排序器 ...

  7. UVA-1322 Minimizing Maximizer (DP+线段树优化)

    题目大意:给一个长度为n的区间,m条线段序列,找出这个序列的一个最短子序列,使得区间完全被覆盖. 题目分析:这道题不难想,定义状态dp(i)表示用前 i 条线段覆盖区间1~第 i 线段的右端点需要的最 ...

  8. poj1769 Minimizing maximizer

    传送门 题目大意 给你m个机器,n个数,每个机器可以给n个数的某一段排序,求最少使用几个机器,保证可以把这个n个数排好序 分析 我们可以想到dpij表示考虑前i个机器让最大的数到达点j至少需要使用多少 ...

  9. Minimizing Maximizer

    题意: 最少需要多少个区间能完全覆盖整个区间[1,n] 分析: dp[i]表示覆盖[1,i]最少需要的区间数,对于区间[a,b],dp[b]=min(dp[a...b-1])+1;用线段树来维护区间最 ...

随机推荐

  1. C#LeetCode刷题之#521-最长特殊序列 Ⅰ​​​​​​​(Longest Uncommon Subsequence I)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3949 访问. 给定两个字符串,你需要从这两个字符串中找出最长的特 ...

  2. LeetCode 763划分字母区间 详解

    题目详情 字符串 S 由小写字母组成.我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段.返回一个表示每个字符串片段的长度的列表. 示例 1: 输入: S = "ab ...

  3. 338. Counting Bits题目详解

    题目详情 Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate ...

  4. Android 开发学习进程0.17 Android资源文件selector textview显示两种不同字体

    selector 是安卓资源文件的一种,它可以使按钮等实现不同状态下的不同UI,不用在代码中实现,而使用方式有两种,一种在color文件下 创建.xml可以使按钮等字体在不同状态下的变化,其二是在dr ...

  5. JS实例-DOM查询

    <!DOCTYPE html><html lang="en"><head> <meta charset="utf-8" ...

  6. HotSpot的执行引擎-CallStub栈帧

    之前多次提到接触到调用JavaCalls::call()方法来执行Java方法,如: (1)Java主类装载时,调用JavaCalls::call()方法执行的Java方法checkAndLoadMa ...

  7. PAT 2-06. 数列求和(20)

    题目意思:给定某数字A(1<=A<=9)以及非负整数N(0<=N<=100000),求数列之和S = A + AA + AAA + … + AA…A(N个A) 最开始一想还以为 ...

  8. HMM隐马尔可夫模型来龙去脉(一)

    目录 隐马尔可夫模型HMM学习导航 一.认识贝叶斯网络 1.概念原理介绍 2.举例解析 二.马尔可夫模型 1.概念原理介绍 2.举例解析 三.隐马尔可夫模型 1.概念原理介绍 2.举例解析 四.隐马尔 ...

  9. Linux内核之 内存管理

    前面几篇介绍了进程的一些知识,从这篇开始介绍内存.文件.IO等知识,发现更不好写哈哈.但还是有必要记录下自己的所学所思.供后续翻阅,同时写作也是一个巩固的过程. 这些知识以前有文档涉及过,但是角度不同 ...

  10. Mybatis进阶使用-一级缓存与二级缓存

    简介 缓存是一般的ORM 框架都会提供的功能,目的就是提升查询的效率和减少数据库的压力.跟Hibernate 一样,MyBatis 也有一级缓存和二级缓存,并且预留了集成第三方缓存的接口. 一级缓存 ...