zoukankan      html  css  js  c++  java
  • Minimizing maximizer(POJ 1769)

    • 原题如下:
      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)时间内求解了。
    • 代码:
        1 #include <cstdio>
        2 #include <cctype>
        3 #include <algorithm>
        4 #define number s-'0'
        5 
        6 using namespace std;
        7 
        8 const int INF=0x3f3f3f3f;
        9 const int MAX_N=500005;
       10 const int MAX_M=500005;
       11 int n,m;
       12 int s[MAX_M], t[MAX_M];
       13 int dp[MAX_N+1];
       14 int dat[4*MAX_N];
       15 
       16 void read(int &x)
       17 {
       18     char s;
       19     bool flag=0;
       20     x=0;
       21     while (!isdigit(s=getchar()))
       22         (s=='-')&&(flag=true);
       23     for (x=number; isdigit(s=getchar());x=x*10+number);
       24     (flag)&&(x=-x);
       25 }
       26 
       27 void write(int x)
       28 {
       29     if (x<0)
       30     {
       31         putchar('-');
       32         x=-x;
       33     }
       34     if (x>9) write(x/10);
       35     putchar(x%10+'0');
       36 }
       37 
       38 void rmq_init(int k, int l, int r);
       39 void update(int u, int v, int k, int l, int r);
       40 int query(int a, int b, int k, int l, int r);
       41 
       42 int min(int x, int y)
       43 {
       44     if (x<y) return x;
       45     return y;
       46 }
       47 
       48 int main(int argc, char * argv[])
       49 {
       50     read(n);read(m);
       51     for (int i=0; i<m; i++)
       52     {
       53         read(s[i]);read(t[i]);
       54         s[i]--;t[i]--;
       55     }
       56     rmq_init(0, 0, n);
       57     fill(dp, dp+MAX_N, INF);
       58     dp[0]=0;
       59     update(0, 0, 0, 0, n);
       60     for (int i=0; i<m; i++)
       61     {
       62         int v=min(dp[t[i]], query(s[i], t[i]+1, 0, 0, n)+1);
       63         dp[t[i]]=v;
       64         update(t[i], v, 0, 0, n);
       65     }
       66     write(dp[n-1]);putchar('
      ');
       67 }
       68 
       69 void rmq_init(int k, int l, int r)
       70 {
       71     dat[k]=INF;
       72     if (r-l==1) return;
       73     rmq_init(k*2+1, l, (l+r)/2);
       74     rmq_init(k*2+2, (l+r)/2, r);
       75 }
       76 
       77 void update(int u, int v, int k, int l, int r)
       78 {
       79     if (r-l==1)
       80     {
       81         dat[k]=v;
       82         return;
       83     }
       84     else
       85     {
       86         int m=(l+r)/2;
       87         if (u<m) update(u, v, k*2+1, l, m);
       88         else update(u, v, k*2+2, m, r);
       89         dat[k]=min(dat[k*2+1], dat[k*2+2]);
       90     }
       91 }
       92 
       93 int query(int a, int b, int k, int l, int r)
       94 {
       95     if (r<=a || b<=l) return INF;
       96     if (a<=l && r<=b) return dat[k];
       97     else 
       98     {
       99         int m=(l+r)/2;
      100         int vl=query(a, b, k*2+1, l, m);
      101         int vr=query(a, b, k*2+2, m, r);
      102         return min(vl, vr);
      103     }
      104 }
  • 相关阅读:
    svn command line tag
    MDbg.exe(.NET Framework 命令行调试程序)
    Microsoft Web Deployment Tool
    sql server CI
    VS 2010 One Click Deployment Issue “Application Validation did not succeed. Unable to continue”
    mshtml
    大厂程序员站错队被架空,只拿着五折工资!苟活和离职,如何选择?
    揭秘!Windows 为什么会蓝屏?微软程序员竟说是这个原因...
    喂!千万别忘了这个C语言知识!(~0 == -1 问题)
    Linux 比 Windows 更好,谁反对?我有13个赞成理由
  • 原文地址:https://www.cnblogs.com/Ymir-TaoMee/p/9573385.html
Copyright © 2011-2022 走看看