Dynamic Programming实战一:Longest Increasing Subsequence算法分析及C代码实现
2015-09-12 18:32
691 查看
最近在基友们的鼓(song)励(yong)下,刚刚开始学习算法,然后准备从动态规划算法开始学起。由于本程序猿只会C,所以实现全部为C实现,请多多包涵。
动态规划算法主要需要找出解决问题的状态以及状态转移方程,以我的观点看来,动态规划有点像高级的递推,即当前的状态需要由前面的状态和状态转移方程推出。下面就具体实例进行分析。
LIS算法是动态规划最经典的题目。该问题需要解决的是在一个给定的有序序列中,找到最长的值升序子序列,子序列不必连续。例如有序序列{5,3,4,8,6,7},其最长值升序子序列为{3,4,6,7}。该问题的解决步骤是:设有序序列x长N,对于前1个数,最长子序列d(1)=1;对于前2个数,如果第2个数大于第1个数,那么d(2)=d(1)+1=2,否则d(2)=1;对于前3个数,如果第3个数大于第1个数,那么d(3)=d(1)+1,如果第3个数大于第2个数,那么d(3)=max(d(1)+1,d(2)+1),如果第3个数比第1个数和第2个数都小,那么d(3)=1...递推下来,前N个数中最长子序列长度d(N)=max{d(i)+1,1},其中i<n,x(i)<x(N)。
如果在过程中加入当前最长子序列的是由哪个状态得出的,最后不但可以求得最长子序列长度,还可以得到最长子序列为何。
C代码如下:
程序输出为:
由输出可以看出,最长值升序子序列长度为6,子序列为{data[1],data[2],data[4],data[5]}即{3,4,6,7}。
动态规划算法主要需要找出解决问题的状态以及状态转移方程,以我的观点看来,动态规划有点像高级的递推,即当前的状态需要由前面的状态和状态转移方程推出。下面就具体实例进行分析。
LIS算法是动态规划最经典的题目。该问题需要解决的是在一个给定的有序序列中,找到最长的值升序子序列,子序列不必连续。例如有序序列{5,3,4,8,6,7},其最长值升序子序列为{3,4,6,7}。该问题的解决步骤是:设有序序列x长N,对于前1个数,最长子序列d(1)=1;对于前2个数,如果第2个数大于第1个数,那么d(2)=d(1)+1=2,否则d(2)=1;对于前3个数,如果第3个数大于第1个数,那么d(3)=d(1)+1,如果第3个数大于第2个数,那么d(3)=max(d(1)+1,d(2)+1),如果第3个数比第1个数和第2个数都小,那么d(3)=1...递推下来,前N个数中最长子序列长度d(N)=max{d(i)+1,1},其中i<n,x(i)<x(N)。
如果在过程中加入当前最长子序列的是由哪个状态得出的,最后不但可以求得最长子序列长度,还可以得到最长子序列为何。
C代码如下:
void LIS(int *data, int cnt) { <span style="white-space:pre"> </span>int *f; <span style="white-space:pre"> </span>int i, j; <span style="white-space:pre"> </span>int pre_pos=1; <span style="white-space:pre"> </span>f=malloc(sizeof(int)*(cnt+1)); <span style="white-space:pre"> </span>for (i=1;i<=cnt;i++) <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>f[i]=1; <span style="white-space:pre"> </span>pre_pos=i; <span style="white-space:pre"> </span>if (i>1) <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>for (j=1;j<i;j++) <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>if ((data[j]>data[j-1])&&(f[i]<f[j]+1)) <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>f[i]=f[j]+1; <span style="white-space:pre"> </span>pre_pos=j; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>printf("at position %d max length is %d, previous position is %d\n",i,f[i],pre_pos); <span style="white-space:pre"> </span>} }
程序输出为:
at position 1 max length is 1, previous position is 1 at position 2 max length is 1, previous position is 2 at position 3 max length is 2, previous position is 2 at position 4 max length is 3, previous position is 3 at position 5 max length is 3, previous position is 3 at position 6 max length is 4, previous position is 5
由输出可以看出,最长值升序子序列长度为6,子序列为{data[1],data[2],data[4],data[5]}即{3,4,6,7}。
相关文章推荐
- POJ 1776 - Task Sequences(哈密顿图)
- UIStatusBarStyle的类型改变
- UISegmentedControl 开发笔记
- Android Dialog中的Builder设计模式
- POJ - 1986 Distance Queries(LCA离线)
- Codeforces Round #316 Tree Requests
- easyui的datagrid为何无法显示json数据
- UI 自定义视图
- iOS开发-------简单通讯录2(UISearchController)
- [Wed, 19 Aug 2015 ~ Tue, 25 Aug 2015] Deep Learning in arxiv
- 关于UIScrollView的几点总结
- Storm UI参数详解
- UIViewContentMode
- IOS开发之手势——UIGestureRecognizer 共存
- Volley框架解析(二)-----Volley及RequestQueue解析
- Android 4.4 Kitkat Phone工作流程浅析(二)__UI结构分析
- HDU 1503 Advanced Fruits(LCS+输出路径)
- IOS UILabel 设置圆角
- POJ 2533 Longest Ordered Subsequence(DP最长上升子序列O(n^2)&&O(nlogn))
- iOS UItableview加载图片的时候的优化之lazy(懒加载)模式and异步加载模式