最強増分部分数列(LIS)アルゴリズム
最大増分部分数列(LIS)アルゴリズム
最大インクリメンタルカウントとは?
要素個nの個人配列の部分要素では、各要素が前の要素より大きい条件を満たし、その長さが最も大きい部分数列を最長増分部分数列と呼ぶ.
通常LISの簡便な方法としてはDPがある.
for (int k=0; k<n; k++){
length[k] = 1;
for (int i=0; i<k; i++){
if(arr[i] < arr[k]){
length[k] = max(length[k], length[i] + 1);
}
}
}
上記のコードでは、length[I]は、iの最初のインデックスに終了する最長増分部分数列の長さを表す.更新条件:
二分ナビゲーションを使用したLIS
LISの形態を維持するために,所与の配列のインデックスを1つずつ表示し,その数値を二分ナビゲーションで入れる.
この探索は一般に時間的複雑度がO(logn)であると考えられるため,O(blog)の時間的複雑度で上記の問題を解決することができる.
int n;
int arr[40001];
int lis[40001];
int binarySearch(int left, int right, int target){
int mid;
while(left<right){
mid = (left+right)/2;
if(lis[mid] < target){
left = mid+1;
}
else{
right = mid;
}
}
return right;
}
int main(){
int n;
cin >> n;
for(int i=0; i<n; i++){
cin >> arr[i];
}
int j=0;
lis[0] = arr[0]
int i=1;
while(i<n){
if(lis[j] < arr[i]){
lis[j+1] = arr[i];
j+=1
}
else{
int pos = binarySearch(0,j,arr[i]);
lis[pos] = arr[i];
}
i+=1;
}
cout<< j+1;
return 0;
}
上のコードはLISの長さを求める方法だけです.実際のLISを手に入れたい場合は、次の方法を使用します.
REFERENCE
画像ソース:https://yhwan.tistory.com/21
Reference
この問題について(最強増分部分数列(LIS)アルゴリズム), 我々は、より多くの情報をここで見つけました https://velog.io/@seho100/최강-증가-부분-수열LIS-알고리즘テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol