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++不是很熟,没看懂……以后要加油啊……
- POJ 2533
- POJ 2533
- POJ 2533
- poj 2533
- POJ 2533
- poj-2533
- poj--2533
- poj 2533
- POJ 2533
- POJ 2533
- POJ 2533
- poj 2533
- POJ-2533
- POJ 2533
- POJ 2533
- POJ 2533
- POJ 2533 O(NLogN)
- poj 2533 LCS
- Unix/Linux 编程实践教程 第7章 笔记(1)
- Android菜鸟笔记-利用CountDownTimer实现倒计时功能
- leetcode:Palindrome Partitioning II
- android编程中遇到的关于java.io.FileNotFoundException: /mnt/sdcard/update.zip (Permission denied)错误的原因及解决办法
- Linux_平坦内存模式
- POJ 2533
- iOS数据存储的四种方案对比
- 每日阅读9之linux内核设计与实现——中断上半部与下半部
- 【C语言】-->语法 fgets函数原理初探
- Android ViewHolder
- Android 多级菜单
- 自定义分数类
- Wireless LAN Architecture
- Qt 资源系统