我正在阅读增长最长的子序列问题: 给定数组A = {a_1,a_2,...,a_n},找到最长增长子序列的长度(不一定是连续的) 我想到了一个递归解决方案,其中memoization(或DP)具有复杂度= O(n * max(a_i))。 所以基本上是n *范围的a_i。 我找到的所有解决方案都是O(n ^ 2)或O(nlogn),这个解决方案在逻辑上有什么问题吗?
这是代码: 不失一般性,假设所有a_i的> 0
#include <iostream>
using namespace std;
int count = 0;
int lis(int A[], int loc, int length, int ** table, int max_so_far=0){
count++;
if (loc == length)
return 0;
if (table[loc][max_so_far] != -1)
return table[loc][max_so_far];
int val1 = 0, val2 = 0;
val1 = lis(A, loc+1, length, table, max_so_far);
if (max_so_far < A[loc])
val2 = 1 + lis(A, loc+1, length, table, A[loc]);
table[loc][max_so_far] = max(val1,val2);
return max(val1,val2);
}
int main(){
int A[]={10, 11, 12, 9, 8, 7, 5, 6};
int A[]={1,3,2,5,1,3,2,5,1,3,2,5,1,3,2,5,1,3,2,5,1,3,2,5,1,3,2,5, 1,3,2,5, 1,3,2,5, 1,3,2,5, 1,3,2,5, 1,3,2,5};
int ** table;
int n = 49;
int range = 6;
table = new int*[n];
for (int i =0;i<n;i++){
table[i] = new int[range];
for(int j=0;j<range;j++)
table[i][j] = -1;
}
count = 0;
cout<<lis(A, 0, n, table, 0)<<endl;
cout<<"Number of calls made: "<<count<<endl;
return 0;
}
答案 0 :(得分:0)
这只是编写标准O(n ^ 2)算法的一种复杂且空间效率低的方法。
答案 1 :(得分:0)
我认为你接近没有任何问题。正如你所说,复杂性是O(n * | A |)其中| A |是唯一元素的数量。在最坏的情况下,| A | = n。