题:求一个一维数组arr[i]中的最长递增子序列的长度,如在序列1,-1,2,-3,4,-5,6,-7中,最长递增子序列长度为4,可以是1,2,4,6,也可以是-1,2,4,6。
从后向前分析,很容易想到,第i个元素之前的最长递增子序列的长度要么是1(单独成一个序列),
要么就是第i-1个元素之前的最长递增子序列加1,可以有状态方程:
LIS[i] = max{1,LIS[k]+1},其中,对于任意的k<=i-1,arr[i] > arr[k] ,
这样arr[i]才能在arr[k]的基础上构成一个新的递增子序列。
#include <iostream> using namespace std; /* 最长递增子序列 LIS * 设数组长度不超过 30 * DP */ int dp[31]; /* dp[i]记录到[0,i]数组的LIS */ int lis; /* LIS 长度 */ int LIS(int * arr, int size) { for(int i = 0; i < size; ++i) { dp[i] = 1; for(int j = 0; j < i; ++j) { if(arr[i] > arr[j] && dp[i] < dp[j] + 1) { dp[i] = dp[j] + 1; if(dp[i] > lis) { lis = dp[i]; } } } } return lis; } /* 输出LIS */ void outputLIS(int * arr, int index) { bool isLIS = 0; if(index < 0 || lis == 0) { return; } if(dp[index] == lis) { --lis; isLIS = 1; } outputLIS(arr,--index); if(isLIS) { printf("%d ",arr[index+1]); } } void main() { int arr[] = {1,-1,2,-3,4,-5,6,-7}; /* 输出LIS长度; sizeof 计算数组长度 */ printf("%d\n",LIS(arr,sizeof(arr)/sizeof(int))); /* 输出LIS */ outputLIS(arr,sizeof(arr)/sizeof(int) - 1); printf("\n"); }
原文地址:http://www.cnblogs.com/sjw1357/p/3836121.html