演算法詳解 LIS優化

2021-08-21 13:56:32 字數 1965 閱讀 3530

我們知道,lis(最長上公升子串行,最長下降子串行,最長不上公升子串行,最長不下降子串行)如果按照最初得方法做,我們設定的狀態f[i]表示i結尾的最長lis的長度,在列舉每乙個數的時候都要向前找乙個數字,那麼這種方法是o(n^2).(具體講解看這裡)

如果n≤700000呢?o(n^2)的演算法顯然是不符合要求的,我們可以考慮優化lis的dp

我們以最長上公升子串行為例:

我們設f[i]為長度為i的最長上公升子串行結尾的最小個數.

那麼,我們在列舉新的數字a[i]的時候,如果a[i]要比列舉的f[j]大,則說明以a[i]結尾必然能夠形成長度為j+1的最長上公升子串行.我們可以選擇來模擬這個過程.

設這串串行為{2,1,6,5,8,0,1,5,10}

1.因為沒有數字,f=

2.因為1比2小,1無法接在任何數字後面,所以替代2,f=

3.因為6比任何乙個數都要大,所以接在最前面,f=

4.5可以接在1後面並且比6要小,以此代替6,f=

5.因為8比任何數要大,接在末尾,f=

6.0比任何數都要小,所以f=

7.1可以接在0後面,所以f=

8.5可以接在8後面,所以f=

9.10可以接在5後面,所以f=

因為f[4]不為0,說明可以構成長度為4的最長上公升子串行,故答案為4

為什麼我們要在新的數字要是f陣列內的原有值最小?因為這樣更可以讓後面的數字構成最長上公升組序列.因此我們需要在這個序列中查詢,找到乙個位置使得前面的數比它小並且後面的數字大於等於它,使得它能夠覆蓋這個數字.那麼,這個演算法的時間複雜度仍然後o(n^2),顯然無法優化.

不難發現,這個序列是單調遞增的,那麼我們便可以選擇在查詢的時候去優化,在單調遞增的序列中我們可以需用二分查詢去尋找那個可以覆蓋的位置,而二分查詢的時間複雜度是o(lgn),再加上列舉1-n的時間複雜度,故總複雜度為:o(n)*o(logn)=o(nlogn),顯然可以做到.

再重新說一下大致思路:

1.列舉a[1…n]這些數字

2.如果這個陣列比f陣列末尾的數子要大,說明不能覆蓋任何乙個數字,則放在最後

3.否則,用二分查詢進行查詢位置並進行覆蓋.

同理,另外3中lis也可以實現.

有乙個需要注意的地方,那就是:如果做上公升的和不下降的lisf[0]需要賦值為-∞,否則賦值為+∞,我在這裡用pow(10,9)(即10的9次方的意思)在進行f[0]的初始化.因為可能會出現負數

有n個整數,輸出這n個整數的最長上公升序列、最長下降序列、最長不上公升序列和最長不下降序列。

根據上述分析,我們應該十分容易就能夠寫出最後的程式,四個序列的**基本相似

**如下:

#includeusing namespace std;

int n;

int a[800000];

int f[800000];

void lis1()

if (a[i]>f[l]) pos=r;

else pos=l;

f[pos]=min(f[pos],a[i]);

}} cout<>1;

if (a[i]>1;

if (a[i]<=f[mid]) l=mid;

else r=mid;

}if (a[i]<=f[l]) pos=r;

else pos=l;

f[pos]=max(f[pos],a[i]);

} }cout<=f[len]) f[++len]=a[i];

else

if (a[i]>=f[l]) pos=r;

else pos=l;

f[pos]=min(f[pos],a[i]);

} } cout<>n;

for (int i=1;i<=n;i++)

cin>>a[i];

lis1();

lis2();

lis3();

lis4();

return 0;

}

LIS 樹狀陣列優化

lis 即最長上公升子串行 可以用dp求解 複雜度o n 2 我們考慮優化 用樹狀陣列 或者線段樹 樹狀陣列維護區間最大值 省去原始o n 2 演算法中的查詢 這樣還能求出以i結尾的lis 二分只能求出當前序列的lis 許多題裡要求lis個數什麼的qwq 總之比二分方便 除了碼量長 還有乙個小點就是...

LIS優化 佇列優化 二分

mbp送去維修的第5天。給定一長度為n的數列,請在不改變原數列順序的前提下,從中隨機的取出一定數量的整數,並使這些整數構成單調上公升序列。輸出這類單調上公升序列的最大長度。資料範圍 1 n 100000 輸入包括兩行,第一行為n,代表數列的長度。第二行為n個整數。輸出這類單調上公升序列的最大長度 5...

深度學習之優化演算法詳解

梯度下降 batch gradient descent,stochastic gradientdescent,以及 mini batchgradient descent 現在的 sgd一般都指 mini batch gradient descent sgd就是每一次迭代計算 mini batch 的...