POJ 2533

来源:互联网 发布:淘宝模特 pose 编辑:程序博客网 时间:2024/05/10 21:54

题目大意:

在给出的长度为m的数字序列{a[m]}中,寻找最长的上升子序列,上升子序列是指,该序列中对于任意i<j,都有a[i]<a[j]。

----------------------------------------我是华丽的分割线------------------------------------------

好吧,这一道是最长上升子序列的经典题目,为什么做这道,是我想用我在POJ1088里面学到的东西来做一下。这回是一下就过了,有进步,勉励一下自己!!奋斗

当然了,我还是用搜索做的,有了POJ1088的经验呢,发现这个的搜索空间实际上是一个相交的森林。假设每一个节点都是 原来序列中的a[i],

1.所有的父节点的序号值都小于子节点

2.所有的父节点的数值都小于子节点

3.所求的解,就是森林中最高的树的高度。

所以,算法就是,从节点i不断向下搜索(子节点序号>i,且数值>a[i]),直到到达底部节点(没有数据满足子节点的条件了),然后再退回。搜索过程中用一个数组来记录节点到目前为止的最大高度,等遍历完所有的节点以后,最后再从所有节点中选出一个高度最大的节点,它的高度就是节。

不过,这个问题的这个解法还只是递归形式的解法。从上面的表述中发现这个肯定可以用动态规划做的(根据算法导论,上面的解法就是动态规划的第二步骤的实现解法)。

先贴出递归解法:

#include <stdio.h>#include <stdlib.h>int *a;int *c;int len;int findMax(int k){    int cMax=0;  int cTemp=0;  int i,aTemp;    aTemp=a[k];    if (c[k]!=-1){  //到过的节点    return c[k];  }    for (i=k+1;i<len;i++){    if (a[i]>aTemp) {    cTemp=findMax(i)+1;    cMax=cTemp>cMax?cTemp:cMax;    }  }  c[k]=cMax;  return c[k];}int cmp_fun(const void *a,const void *b){  return *(int *)a-*(int *)b;}int main(){  int i;    scanf("%d",&len);    a=(int *)calloc(len,sizeof(int));  c=(int *)calloc(len,sizeof(int));    for (i=0;i<len;i++){    scanf("%d",&(a[i]));    c[i]=-1;  }    for (i=0;i<len;i++){    if (c[i]==-1) findMax(i);   }    qsort(c,len,sizeof(int),cmp_fun);  printf("%d\n",c[len-1]+1);}

然后是动态规划的解法:自低向上的解法

c[i]=max{ c[k] | if (a[k]<a[i] and k<i) }+1,c数组中代表最大长度。

贴代码:

#include <stdio.h>#include <stdlib.h>int *a;int *c;int len;void findMax(){int cMax;int cTemp;int i,j;  for (i=0;i<len;i++){  cMax=0;    for (j=0;j<i;j++){      if (a[j]<a[i]){        cTemp=c[j]+1;        cMax=cMax>cTemp?cMax:cTemp;      }    }    c[i]=cMax;  }}int cmp_fun(const void *a,const void *b){  return *(int *)a-*(int *)b;}int main(){  int i;    scanf("%d",&len);    a=(int *)calloc(len,sizeof(int));  c=(int *)calloc(len,sizeof(int));    for (i=0;i<len;i++){    scanf("%d",&(a[i]));    c[i]=-1;  }  findMax();    qsort(c,len,sizeof(int),cmp_fun);  printf("%d\n",c[len-1]+1);}

好了,到此为止。

后来我在查找别人的代码的同时发现了一种用C++的STL multiset实现的方法,参考http://blog.csdn.net/qingniaofy/article/details/7857623 。对于C++不是很熟,没看懂……以后要加油啊……



原创粉丝点击