再次开始了苦X的coding训练, 话说现在看到一些题,略略的有一些疼呀。
这是肿么了呢。是被上次伤到了么,不管怎么样,这个还是得练起来了,话说时间还是有点紧的,必须抓紧时间训练了。而且必须在coding方面有所提高的,
而想要有所提高,就要对那些算法有比较充分的了解和训练。
今天继续学习动规问题,目前处于初级阶段的应用。Longest Increasing Subsequence 是动规问题中最常见的部分。
这次的题目是zigzag问题,今天暂时没有时间去调试它了。
例题中:
一个序列有N个数:A[1],A[2],…,A[N],求出最长非降子序列的长度。
他是这么分析的:
根据上面找到的状态,我们可以得到:(下文的最长非降子序列都用LIS表示)
- 前1个数的LIS长度d(1)=1(序列:5)
- 前2个数的LIS长度d(2)=1(序列:3;3前面没有比3小的)
- 前3个数的LIS长度d(3)=2(序列:3,4;4前面有个比它小的3,所以d(3)=d(2)+1)
- 前4个数的LIS长度d(4)=3(序列:3,4,8;8前面比它小的有3个数,所以 d(4)=max{d(1),d(2),d(3)}+1=3)
1、当前数据A[i]必须和前面每一个数据A[1]...A[i-1]做比较,从而得出多少个比他小,
2、当前数据的结果d(i)只和前面的数据有关,独立于后面的数据,
感觉后面的数据与前面的数据有交集,前面的数据会影响到后面的数据,这是动规一个最大的特点。一边行走,一边规划。
接着是我要解决的变形的类似的题zigzag:
A sequence of numbers is called a zig-zag sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a zig-zag sequence.
For example, 1,7,4,9,2,5 is a zig-zag sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, 1,4,7,2,5 and 1,7,4,5,5 are not zig-zag sequences, the first because its first two differences are positive and the second because its last difference is zero.
Given a sequence of integers, sequence, return the length of the longest subsequence of sequence that is a zig-zag sequence. A subsequence is obtained by deleting some number of elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.
这是topcoder上的原文,大概意思就是:定义这样一个叫zigzag的序列,它从左到右的差是严格的正负交替。比如1,7,4,9,2,5 , 它们的差是(6,-3,5,-7,3)。
现在就是要找出某一个序列的最长zigzag子序列。子序列的意思就是可以对原序列进行任意数量的数字删除。这也就意味着要与前面的每个数据比较,从而找出最长的序列。
核心伪代码如下:
for x=beg...n
for i=beg...n
if( 满足正负切换的条件 )
d(x) = max( d(x), d(i)+1 );
其中,d(x)是当前要找的序列位置的值, d(i)是前面的已经求出的序列的最长子序列的值。
比如:
对于{ 1, 17, 5, 10, 13, 15, 10, 5, 16, 8 }
前一个数:d(1)=1
前两个数:d(2)=2{1-17=-16} 记录 负数
前三个数:d(3)=3{17-5=12}记录正数
前四个数:d(4)=4{ 17-10=7,5-10=-5, max(d(2)+1,d(3)+1) }可见两个都满足条件,找出最大的;记录负数
前五个数:d(5)=4{ 17-13=4, 5-13=-x, max(d(2)+1, d(3)+1 ) };记录负数
前六个数:d(6) = 5 { 17, 5, }
…………
依次类推,可见,在比较过程中还要记录对应使得最大子序列的倒数两个数的差的正负情况,总而为下面的数做准备。
通过数学归纳的方面,逐渐发现了其特点,可以具体细化程序了。
动规的核心,就是找出状态转移方程,而状态转移需要动态规划总结出来。