求解最长递增子串可分为两种情况,即子串连续或非连续。

例如,对于整数串{1,3,5,1,-1,4,5,3,1,8,3,4,6,2,4,6,7,8,6,4}

其连续递增子串为{2,4,6,7,8},非连续递增子串为{{-1},{1},{2,4,6,7,8}}

连续递增子串的求解思路:

采用动态规划思想,令

lengthOfSubList[k]表示子串{list[0]...list[k]}中最长的连续递增子串长度

lengthOfSubListIncludeK[k]表示子串{list[0]...list[k]}中以list[k]结尾的最长连续递增子串长度

indexOfLastElement[k]表示子串{list[0]...list[k]}中最长的连续递增子串的最后一个元素的位置

lengthOfSubListIncludeK[k] =

          lengthOfSubListIncludeK[k-1]+1,list[k]>=list[k-1]

          1,                              list[k]<list[k-1]

lengthOfSubList[k] = max(lengthOfSubListIncludeK[k],lengthOfSubList[k-1])

indexOfLastElement[k] =

        k,                      lengthOfSubListIncludeK[k]>lengthOfSubList[k-1]

        indexOfLastElement[k-1],lengthOfSubListIncludeK[k]<=lengthOfSubList[k-1]

代码:

 
  
  1. #include <stdlib.h> 
  2. #include <stdio.h> 
  3.  
  4. void MaxIncrementSubList(int list[],int length) 
  5.     //lengthOfSubList[k]表示子串{list[0]...list[k]}中最长的连续递增子串长度 
  6.     //lengthOfSubListIncludeK[k]表示子串{list[0]...list[k]}中以list[k]结尾的最长连续递增子串长度 
  7.     int* lengthOfSubList = (int*)malloc(sizeof(int)*length); 
  8.     int* lengthOfSubListIncludeK = (int*)malloc(sizeof(int)*length); 
  9.     int* indexOfLastElement = (int*)malloc(sizeof(int)*length); 
  10.     int i; 
  11.     //初始化 
  12.     for (i=0;i<length;i++) 
  13.     { 
  14.         lengthOfSubList[i] = 1; 
  15.         lengthOfSubListIncludeK[i] = 1;  
  16.         indexOfLastElement[i] = i;   
  17.     } 
  18.     //按照动态规划思想,计算lengthOfSubList[k]和lengthOfSubListIncludeK[k] 
  19.     for (i=1;i<length;i++) 
  20.     { 
  21.         if (list[i]>=list[i-1]) lengthOfSubListIncludeK[i] = lengthOfSubListIncludeK[i-1]+1; 
  22.         else lengthOfSubListIncludeK[i] = 1; 
  23.         if (lengthOfSubListIncludeK[i]>lengthOfSubList[i-1]) 
  24.         { 
  25.             lengthOfSubList[i] = lengthOfSubListIncludeK[i]; 
  26.             indexOfLastElement[i] = i; 
  27.         } 
  28.         else 
  29.         { 
  30.             lengthOfSubList[i] = lengthOfSubList[i-1]; 
  31.             indexOfLastElement[i] = indexOfLastElement[i-1]; 
  32.         } 
  33.     } 
  34.     //逆序输出最长连续递增子串 
  35.     printf("longest sub list is:\n"); 
  36.     int idx = indexOfLastElement[length-1]; 
  37.     while (list[idx]>=list[idx-1]) 
  38.     { 
  39.         printf("[%d]=%d ",idx,list[idx]); 
  40.         idx--; 
  41.     } 
  42.     printf("[%d]=%d ",idx,list[idx]); 
  43.  
  44. int main() 
  45.     int list[20] = {1,3,5,1,-1,4,5,3,1,8,3,4,6,2,4,6,7,8,6,4}; 
  46.     MaxIncrementSubList(list,20); 
  47.     int a; 
  48.     scanf("%d",&a); 
  49.     return 0; 

 

非连续递增子串的求解思路:

采用动态规划思想,令

lengthOfSubList[k]表示子串{list[0]...list[k]}中最长的非连续递增子串长度

lengthOfSubListIncludeK[k]表示子串{list[0]...list[k]}中以list[k]结尾的最长非连续递增子串长度

indexOfLastElement[k]表示子串{list[0]...list[k]}中最长的非连续递增子串的最后一个元素的位置

lengthOfSubListIncludeK[k] = max(lengthOfSubListIncludeK[i]+1, list[k]>=list[i], i=0..k-1)

lengthOfSubList[k] = max(lengthOfSubListIncludeK[k],lengthOfSubList[k-1])

indexOfLastElement[k] =

        k,                      lengthOfSubListIncludeK[k]>lengthOfSubList[k-1]

        indexOfLastElement[k-1],lengthOfSubListIncludeK[k]<=lengthOfSubList[k-1]

代码:

 
  
  1. #include <stdlib.h> 
  2. #include <stdio.h> 
  3.  
  4. void MaxIncrementSubList(int list[],int length) 
  5.     //lengthOfSubList[k]表示子串{list[0]...list[k]}中最长的非连续递增子串长度  
  6.     //lengthOfSubListIncludeK[k]表示子串{list[0]...list[k]}中以list[k]结尾的最长非连续递增子串长度  
  7.     int* lengthOfSubList = (int*)malloc(sizeof(int)*length); 
  8.     int* lengthOfSubListIncludeK = (int*)malloc(sizeof(int)*length); 
  9.     int* indexOfLastElement = (int*)malloc(sizeof(int)*length); 
  10.     int i,j,max; 
  11.     //初始化 
  12.     for (i=0;i<length;i++) 
  13.     { 
  14.         lengthOfSubList[i] = 1; 
  15.         lengthOfSubListIncludeK[i] = 1;  
  16.         indexOfLastElement[i] = i;   
  17.     } 
  18.     //按照动态规划思想,计算lengthOfSubList[k]和lengthOfSubListIncludeK[k] 
  19.     for (i=1;i<length;i++) 
  20.     { 
  21.         max = lengthOfSubListIncludeK[i]; 
  22.         for (j=0;j<i;j++) 
  23.         { 
  24.             if (list[i]>list[j]) 
  25.             { 
  26.                 lengthOfSubListIncludeK[i] = lengthOfSubListIncludeK[j]+1; 
  27.                 if (max<lengthOfSubListIncludeK[i]) max = lengthOfSubListIncludeK[i]; 
  28.             } 
  29.         } 
  30.         lengthOfSubListIncludeK[i] = max; 
  31.         if (lengthOfSubListIncludeK[i]>lengthOfSubList[i-1]) 
  32.         { 
  33.             lengthOfSubList[i] = lengthOfSubListIncludeK[i]; 
  34.             indexOfLastElement[i] = i; 
  35.         } 
  36.         else 
  37.         { 
  38.             lengthOfSubList[i] = lengthOfSubList[i-1]; 
  39.             indexOfLastElement[i] = indexOfLastElement[i-1]; 
  40.         } 
  41.     } 
  42.     //逆序输出最长非连续递增子串  
  43.     printf("longest sub list is:\n"); 
  44.     int idx = indexOfLastElement[length-1]; 
  45.     int tmp = list[idx]; 
  46.     for (i=idx;i>=0;i--) 
  47.     { 
  48.         if (list[i]<=tmp) 
  49.         { 
  50.             printf("[%d]=%d ",i,list[i]); 
  51.             tmp = list[i]; 
  52.         } 
  53.     } 
  54.  
  55. int main() 
  56.     int list[20] = {1,3,5,1,-1,4,5,3,1,8,3,4,6,2,4,6,7,8,6,4}; 
  57.     MaxIncrementSubList(list,20); 
  58.     int a; 
  59.     scanf("%d",&a); 
  60.     return 0;