您的位置:首页 > 产品设计 > UI/UE

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代码如下:

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}。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: