动态规划求解
int calculate(int a[], int n)
{
int i;
int maxV;
//maxLen[i]代表截止到下标为i(包括i)的最长子序列的长度
int * maxLen = (int *)malloc(n*sizeof(int));
for(i=0;i<n;i++)
{
maxLen[i]=1;
for(int j = 0;j<i;j++)
{
if(a[i]>a[j] && maxLen[j]+1>maxLen[i])
{
maxLen[i] = maxLen[j]+1;
}
}
}
maxV = max(maxLen,n);
free(maxLen);
return maxV;
}
时间复杂的为O(n*n)
进一步分析
如果前i-1个元素的任何一个递增子序列的最大值小于第i个元素,那么就可以构成一个新的递增子序列。重要的是我们要保证新的递增子序列尽可能的长。
int calculate(int a[],int n) { int i,j; //如果存在含有元素相同个数的多个子序列,长度为i,将多个子序列的最大值中的最小值存入minV[i] int * maxV = (int *)malloc(sizeof(int) * (n+1)); //maxLen[i]代表截止到下标为i(包括i)的最长子序列的长度 int * maxLen = (int *)malloc(sizeof(int) * n); //记录最长子序列的长度,初始为1 int max = 1; maxV[1] = a[0]; maxV[0] = min(a,n)-1; for(i=0;i<n;i++) { //初始化为1 maxLen[i]=1; } for(i=1;i<n;i++) { for(j=max;j>=0;j--) { //如果当前值a[i]大于长度为j的递增子序列,则可以构成长度为j+1的递增子序列。 if(a[i]>maxV[j]) { maxLen[i]=j+1; break; } } } //如果截止到下标为i(包括i)的最长子序列的长度大于记录max,则将max赋值为maxLen[i] if(maxLen[i]>max) { max=maxLen[i]; //该长度为maxLen[i]的子序列的最大值一定为a[i] maxV[maxLen[i]]=a[i]; } else if(maxV[j] < a[i] && a[i] < maxV[j+1]) { maxV[j+1] = a[i]; } free(maxV); free(maxLen); return max; }
时间复杂度O(n*n)
参考书籍:《编程之美》