簡體   English   中英

沒有動態編程的最長增長子序列算法的復雜性是什么以及如何計算

[英]What is the complexity of Longest increasing sub sequence algorithm without dynamic programming and how to compute it

這是LIS的GeeksForGeeks的代碼。

 /* To make use of recursive calls, this function must return
   two things:
   1) Length of LIS ending with element arr[n-1]. We use
  max_ending_here for this purpose
   2) Overall maximum as the LIS may end with an element
  before arr[n-1] max_ref is used this purpose.
  The value of LIS of full array of size n is stored in 
  *max_ref which is our final result */
int _lis( int arr[], int n, int *max_ref)
 {
/* Base case */
if (n == 1)
    return 1;

// 'max_ending_here' is length of LIS ending with arr[n-1]
int res, max_ending_here = 1; 

/* Recursively get all LIS ending with arr[0], arr[1] ... 
   arr[n-2]. If   arr[i-1] is smaller than arr[n-1], and 
   max ending with arr[n-1] needs to be updated, then 
   update it */
for (int i = 1; i < n; i++)
{
    res = _lis(arr, i, max_ref);
    if (arr[i-1] < arr[n-1] && res + 1 > max_ending_here)
        max_ending_here = res + 1;
 }

// Compare max_ending_here with the overall max. And 
// update the overall max if needed
if (*max_ref < max_ending_here)
   *max_ref = max_ending_here;

// Return length of LIS ending with arr[n-1]
return max_ending_here;
}

// The wrapper function for _lis()
int lis(int arr[], int n)
 {
  // The max variable holds the result
int max = 1;

// The function _lis() stores its result in max
_lis( arr, n, &max );

// returns max
return max;
}

 /* Driver program to test above function */
int main()
 {
   int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
   int n = sizeof(arr)/sizeof(arr[0]);
   printf("Length of LIS is %d\n",  lis( arr, n ));
   return 0;
 }

這就是樹。如何通過它計算算法的復雜度? 是否有一些適當的方法來計算此類算法的復雜度,或者程序員可以直觀地進行計算,並且在應用動態編程后如何將復雜度降低為0(n ^ 2)

                 lis(4)   

             /       |      \
        lis(3)      lis(2)    lis(1)  
       /     \        /         
   lis(2)  lis(1)   lis(1) 
   /    
lis(1) 

假設對於輸入大小n = f(n)無需動態編程的解決方案的復雜性

現在,觀察復發:
f(n)= f(n-1)+ f(n-2)+ f(n-3)+ ... + f(1)
遞歸f(n-1)= f(n-2)+ f(n-3)+ ... f(1)

顯然,我們可以觀察到f(n)= 2 * f(n-1)
所以我們的緊湊遞推關系是f(n) = 2*f(n-1)

f(n)= 2 * f(n-1)
f(n-1)= 2 * f(n-2)
...
f(2)= 2 * f(1)
f(1)= 2 * f(0)

在上述方程中,將第i個方程乘以2 ^(i-1),然后將所有方程相加。 顯然,我們有f(n)=(2 ^ n)* f(0)= O(2 ^ n)

因此,復雜度是指數= O(2^n)

現在讓我們看看使用動態編程時會發生什么。 使用DP時,一旦計算f(n),就將其保存下來,這樣就不會在遞歸中再次計算它。 這給我們留下了:
f(n)= f(n-1)+ f(n-2)+ ... f(1)
但是這一次,當f(n-1)的遞歸調用計算f(n-2),f(n-3)等時,我們在計算f(n)時不必重新計算它。

所以現在f(n)= n +(n-1)+(n-2)+ ... 1這是O(n^2)
希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM