日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

子序列问题

發布時間:2024/8/26 综合教程 25 生活家
生活随笔 收集整理的這篇文章主要介紹了 子序列问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最長上升子序列

n^2做法,和簡單用前一個更新,不說了;

nlogn算法:

以下轉自博客

D_Double's Journe

此外,我們用一個變量Len來記錄現在最長算到多少了

首先,把d[1]有序地放到B里,令B[1] = 2,就是說當只有1一個數字2的時候,長度為1的LIS的最小末尾是2。這時Len=1

然后,把d[2]有序地放到B里,令B[1] = 1,就是說長度為1的LIS的最小末尾是1,d[1]=2已經沒用了,很容易理解吧。這時Len=1

接著,d[3] = 5,d[3]>B[1],所以令B[1+1]=B[2]=d[3]=5,就是說長度為2的LIS的最小末尾是5,很容易理解吧。這時候B[1..2] = 1, 5,Len=2

再來,d[4] = 3,它正好加在1,5之間,放在1的位置顯然不合適,因為1小于3,長度為1的LIS最小末尾應該是1,這樣很容易推知,長度為2的LIS最小末尾是3,于是可以把5淘汰掉,這時候B[1..2] = 1, 3,Len = 2

繼續,d[5] = 6,它在3后面,因為B[2] = 3, 而6在3后面,于是很容易可以推知B[3] = 6, 這時B[1..3] = 1, 3, 6,還是很容易理解吧? Len = 3 了噢。

第6個, d[6] = 4,你看它在3和6之間,于是我們就可以把6替換掉,得到B[3] = 4。B[1..3] = 1, 3, 4, Len繼續等于3

第7個, d[7] = 8,它很大,比4大,嗯。于是B[4] = 8。Len變成4了

第8個, d[8] = 9,得到B[5] = 9,嗯。Len繼續增大,到5了。

最后一個, d[9] = 7,它在B[3] = 4和B[4] = 8之間,所以我們知道,最新的B[4] =7,B[1..5] = 1, 3, 4, 7, 9,Len = 5。

于是我們知道了LIS的長度為5。

!!!!! 注意。這個1,3,4,7,9不是LIS,它只是存儲的對應長度LIS的最小末尾。有了這個末尾,我們就可以一個一個地插入數據。雖然最后一個d[9] = 7更新進去對于這組數據沒有什么意義,但是如果后面再出現兩個數字 8 和 9,那么就可以把8更新到d[5], 9更新到d[6],得出LIS的長度為6。

然后應該發現一件事情了:在B中插入數據是有序的,而且是進行替換而不需要挪動——也就是說,我們可以使用二分查找,將每一個數字的插入時間優化到O(logN)~~~~~于是算法的時間復雜度就降低到了O(NlogN)~!

簡單來說就是做一個數列保存 構成該長度子序列的所有可能中最后一個數最小的 那個序列的最后一個數,可以用二分優化,因為序列一定是上升的嘛!

#include<cstdio>
#include<iostream>
using namespace std;
int ans[100000];
int a[100000];int len=1;
inline int mid_serch(int x)
{
    int l=0,r=len;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(ans[mid]<a[x])l=mid+1;
        else r=mid-1;
    }
    return l;
} 
int main()
{
    int m;
    scanf("%d",&m);
    for(int i=1;i<=m;++i)scanf("%d",a+i);
    ans[1]=a[1];
    for(int i=2;i<=m;++i)
    {
        if(a[i]>ans[len])
        ans[++len]=a[i];
        else {
            int tmp=mid_serch(i);
            ans[tmp]=a[i];
        }
    }
    printf("%d",len);
}

最長公共子序列 n ^2

lcs 設 A B 串

用dp[i][j]表示只考慮A串前i位,B串前j位的LCS長度。
要么A[i]和B[j]匹配不上 要么放棄A[i]要么放棄B[j]。
輕易地可以設計出狀態轉移方程。
if (a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
復雜度O(n^2),轉移O(1);

O(“nlogn”)做法

做一個序列,保存:

串B與串A所匹配字符在串A中的位置

然后求該序列的最長上升子序列

(從前往后排)

,若果匹配項少的話復雜度 為O(nlogn)反之退化為O(n^n);

總結

以上是生活随笔為你收集整理的子序列问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。