动态规划 ship

<Discription>

PALMIA国家被一条河流分成南北两岸,南北两岸上各有N个村庄。北岸的每一个村庄有一个唯一的朋友在南岸,且他们的朋友村庄彼此不同。每一对朋友村庄想要一条船来连接他们,他们向政府提出申请以获得批准。由于河面上常常有雾,政府决定禁止船只航线相交(如果相交,则很可能导致碰船)。你的任务是编写一个程序,帮助政府官员决定比准哪些船只航线,使得不相交的航线数目最大。

<input>

输入有几组数据组成。每组数据的第一行有2个整数X,Y,中间有一个空格隔开,X代表PALMIA河的长度(10<=X<=6000),Y代表河的宽度(10<=Y<=100)。第二行包含整数N,表示分别坐落在南北两岸上的村庄的数目(1<=N<=5000)。在接下来的N行中,每一行有两个非负整数C,D,由一个空格隔开,分别表示这一对朋友村庄沿河岸与PALMIA河最西边界的距离(C代表北岸的村庄,D代表南岸的村庄),不存在同岸又同位置的村庄。最后一组数据的下面仅有一行,是两个0,也被一行空格隔开。

<output>

对输入的每一组数据,输出最大可能满足上述条件的航线的数目。

<input example>

30 4

7

22 4

2 6

10 3

15 12

9 8

17 17

4 2

0 0

<output example>
4

 

 

<问题分析>

两条线路相交的条件为C1>C2,D1<D2或者C1<C2,D1>D2。若不相交,则有C1<D1,C2<D2。

由此先对一边的村子位置进行排序,再根据序号,找出另一边村子的最长非降序列。

//ship

#include <stdio.h>
#include <algorithm>
#include <stdlib.h>


struct TP
{
   int p1;
   int p2;
};

int cmp(const void *t1,const void *t2)
{
   struct TP *t11,*t22;
   t11=(TP *)t1;
   t22=(TP *)t2;
   return t11->p1>t22->p1;
}

int main()
{
    int x,y,n,i,j,val[5001];
    struct TP tp[5001];
    while(true)
    {
        scanf("%d %d",&x,&y);
        if(!x&&!y) break;
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
           scanf("%d %d",&(tp[i].p1),&(tp[i].p2));
        }
        for(i=0;i<n;i++)
          val[i]=1;
        qsort(tp,n,sizeof(tp[0]),cmp);
        /*
        for(i=1;i<n;i++)
        {
            printf("%d ",tp[i].p1);
        }
        printf("\n");
        */
        for(i=1;i<n;i++)
        {
           for(j=0;j<i;j++)
           {
              if(tp[i].p1>=tp[j].p1&&tp[i].p2>=tp[j].p2)
                if(val[i]<val[j]+1)
                  val[i]=val[j]+1;
           }
        }
        j=0;
        for(i=0;i<n;i++)
        {
           if(j<val[i])j=val[i];
           //printf("%d ",val[i]);
        }
        //printf("\n");
        printf("%d\n",j);
    }
    return 0;
}

  

posted @ 2013-06-30 15:55  simplesslife  阅读(614)  评论(0编辑  收藏  举报