zoukankan      html  css  js  c++  java
  • 序列DP:线段覆盖

    题目描述 
    Description

        给定x轴上的N(0<N<100)条线段,每个线段由它的二个端点a_I和b_I确定,I=1,2,……N.这些坐标都是区间(-999,999)的整数。有些线段之间会相互交叠或覆盖。请你编写一个程序,从给出的线段中去掉尽量少的线段,使得剩下的线段两两之间没有内部公共点。所谓的内部公共点是指一个点同时属于两条线段且至少在其中一条线段的内部(即除去端点的部分)。

    输入描述 Input Description

        输入第一行是一个整数N。接下来有N行,每行有二个空格隔开的整数,表示一条线段的二个端点的坐标。

    输出描述 Output Description

        输出第一行是一个整数表示最多剩下的线段数。

    样例输入 Sample Input

    3

    6  3

    1  3

    2  5

    样例输出 Sample Output

    2

    数据范围及提示 
    Data Size & Hint
    0<N<100

    从一开始做这道题,别人就告诉我说,要用贪心,我就是始终理解不了贪心的奥秘。
    so,就用DP来做这道题吧。
    读入:这一点特别坑,读入时起点可能大于终点
    所以要判断大小。
    在处理数据之前,要根据起点排序。
    用a[i]来表示起点,b[i]来表示终点
    f[i]代表在第i条线段之前最多有多少条可剩下的线段
    当0<j<i时,如果a[i]>=b[j]{题目中说,可以存在边缘公共点}
    则得到状态转移方程:f[i]:=max(f[j]}+1;{0<j<i}
    var n:longint;{线段个数}
    a{起点},b{终点}:array[1..100]of longint;
    f:array[1..100]of longint;{最多剩下的线段数}
    i,j,k:longint;
    findmax:longint;
    function min(x,y:longint):longint;
    begin if x>y
    then exit(y)
    else exit(x);
    end;
    function max(x,y:longint):longint;
    begin if x>y
    then exit(x)
    else exit(y);
    end;
    procedure qsort(s,t:longint);
    var head,tail,k,temp1,temp2:longint;
    begin head:=s; tail:=t;
    k:=a[(head+tail) div 2];
    while head<tail do
    begin while a[head]<k do inc(head);
    while k<a[tail] do dec(tail);
    if head<=tail
    then begin temp1:=a[head];
    a[head]:=a[tail];
    a[tail]:=temp1;
    temp2:=b[head];
    b[head]:=b[tail];
    b[tail]:=temp2;
    inc(head);
    dec(tail);
    end;
    end;
    if head<t then qsort(head,t);
    if s<tail then qsort(s,tail);
    end;

    begin
    readln(n);
          for i:=1 to n do
    begin readln(j,k);
    a[i]:=min(j,k);
    b[i]:=max(j,k);
    end;
    qsort(1,n);
    f[1]:=1;
    for i:=2 to n do
    begin findmax:=0;
    for j:=1 to i-1 do
    if (a[i]>=b[j])and (f[j]>findmax)
    then findmax:=f[j];
    if findmax<>0
    then f[i]:=findmax+1
    else f[i]:=1;
    end;
    findmax:=0;
    for i:=1 to n do
    if f[i]>findmax
    then findmax:=f[i];
    write(findmax);
    end.
  • 相关阅读:
    团队里A和B吵架了,经理M该干啥?
    一个程序员的哲学思考(关于编程、关于人生)
    程序员在大学里究竟应该学习什么?
    如何检查自己是否平庸?
    关于如何读代码?
    老说技术更迭快,可十年到底可以淘汰多少知识?
    现代软件工程里的困惑
    略谈各国企业的差异
    Silverlight4Beta之操作摄像头/麦克风
    Silverlight4Beta之Binding新特性(下)
  • 原文地址:https://www.cnblogs.com/spiderKK/p/4293044.html
Copyright © 2011-2022 走看看