首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

最长递加子序列及应用

2012-09-04 
最长递增子序列及应用最长递增子序列输入序列X:5,9,4,8,3,7,6,10,则输出该序列的最长递增子序列的长度为3,

最长递增子序列及应用

最长递增子序列

    输入序列X:5,9,4,8,3,7,6,10,则输出该序列的最长递增子序列的长度为3,其中一个最长递增子序列为5,9,10.

两种思路(基于动态规划方法求解)

思路1  将序列X递增排序为序列Y:3,4,5,6,7,8,9,10,原问题就转化成求X,Y两个序列的最长公共子序列问题.(本文不提供具体解法)

思路2  设f[i]表示以下标i结尾的最长递增子序列的长度

             则: f[0] = 1   for i = 0

                      f[i] = max{max{f[j]+1 | 0=< j < i 且X[j] <= X[i]} , 1}   for 0 < i < n

             设pre[i]表示以下标i结尾的最长递增子序列中下标i对应的元素的前驱元素对应的下标(-1表示没有前驱)

例:5,9,4,8,3,7,6,10

        f[0]   = 1      pre[0]  = -1        5(序列)

        f[1]   = 2      pre[1]  =  0        5,9

        f[2]   = 1      pre[2]  = -1        4

        f[3]   = 2      pre[3]  = 0         5,8

        f[4]   = 1      pre[4]  = -1        3

        f[5]   = 2      pre[5]  = 0         5,7

        f[6]   = 2      pre[6]  = 0         5,6

        f[7]   = 3      pre[7]  = 1         5,9,10

则最长递增子序列的长度为3,其中一个最长递增子序列为5,9,10(通过pre构造).

具体代码实现如下:

/************************************************************************//* Input: (ht,wt)          (65,100) (70,150) (56,90) (75,90) (60,95) (68,110)    Output: longest tower 6           (56,90) (60,95) (65,100) (68,110) (70,150) (75,190)          *//************************************************************************/struct Person{int m_ht;  //身高int m_wt;  //体重};//比较算子,以身高优先比较,在身高相同的情况下比较体重int compare(const void* p1, const void* p2){int x1 = ((Person*)p1)->m_ht;int y1 = ((Person*)p1)->m_wt;int x2 = ((Person*)p2)->m_ht;int y2 = ((Person*)p2)->m_wt;if(x1 > x2){return 1;}else if(x1 == x2){return y1-y2 >= 0 ? !!(y1-y2) : -1;}else{return -1;}}int getLargestNumOfPeople(Person* pPerson, int n, Person* pRes){if(pPerson == NULL || pRes == NULL || n <= 0) return -1;int* pWt = new int[n];qsort(pPerson,n,sizeof(Person),compare);for(int i = 0; i < n; ++i){pWt[i] = pPerson[i].m_wt;}int* nPreIndx = new int[n];int index;int largestN = maxIncreaseSubSequence(pWt,n,nPreIndx,index);int* pMaxSub = MISubSequence(nPreIndx,index);int j = 0;for(i = pMaxSub[0]; i > 0; --i,++j){pRes[j] = pPerson[pMaxSub[i]];}delete[] pMaxSub;return largestN;}



热点排行