最長上公升子串行(優化)

2021-10-19 08:14:51 字數 1672 閱讀 7330

先寫一下dp普通演算法

f[i]以第i個數結尾的最長上公升子串行的長度

每乙個上公升子串行包括自己,將每乙個值初始化為1,之後遍歷之前的值,如果該值大於之前的值,則比較是現在的值大還是之前某個值加1大。最後答案不是為f陣列的最後乙個數,因為最長上公升子串行不一定以最後乙個數為結尾。

轉移方程

if(w[i]>w[j])

f[i]=max(f[j]+1,f[i])

#include

#include

#include

using

namespace std;

int w[

1001];

int f[

1001];

intmain()

ans=

max(ans,f[i]);

} cout

}

普通演算法的時間複雜度為o(n^2),如果資料容量過大,肯定會超時的。

定義乙個輔助陣列,用於儲存最長上公升子串行,且其中的元素均達到能達到的最小狀態。先把f[1]設為w[1],之後遍歷w陣列的每個元素,判斷它是否大於f陣列的尾元素,如果大於,則把它也加入到f陣列之中;如果不大於,則從頭遍歷f陣列,如果該數小於其中乙個數,將其替換,因為f陣列中的數越小越好,其越小,後面的數才容易進入。為什麼可以替換呢?比如f陣列原來是1 5 7 8,需要判斷的數為4,4大於1,不能替換,繼續,4小於5,可以替換。需要替換的數肯定小於被替換的數,大於被替換的數的前乙個數,替換後保證原陣列還是上公升的。這樣就能做到每乙個數都盡可能得小,是一種貪心的演算法。最後的答案就為f陣列的長度

注意替換的判斷條件是小於等於,如果小於的話,碰見乙個相等的數,在此處沒有替換,它肯定會比下乙個數小,然後把下乙個數替換掉,從而導致了序列中有了兩個相等的數,影響後面所有的判斷。

另外,替換掉乙個記得退出迴圈

#include

#include

#include

using

namespace std;

int w[

100001];

int f[

100001];

intmain()

} cout

}

這麼算在查詢第乙個小於的數時,可能還會消耗大量時間,可以使用二分查詢優化。這樣優化後時間複雜度為o(nlogn)

#include

#include

#include

using

namespace std;

int w[

100001];

int f[

100001];

intmain()

else

l=mid+1;

} f[t]

=w[i];}

} cout

}

#include

#include

#include

using

namespace std;

int w[

100001];

int f[

100001];

intmain()

} cout<}

優化 最長上公升子串行 最長上公升子串行解題報告

給定乙個長度為n的數列 w n 求數值嚴格單調遞增的子串行的長度最長是多少。輸入格式 第一行包含整數n。第二行包含n個整數,表示完整序列。輸出格式 輸出乙個整數,表示最大長度。資料範圍 1 n 1000,1e9 數列中的數 1e9 輸入樣例 7 3 1 2 1 8 5 6 輸出樣例 4 includ...

最長上公升子串行

問題描述 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 等等...

最長上公升子串行

最長上公升子串行問題是各類資訊學競賽中的常見題型,也常常用來做介紹動態規劃演算法的引例,筆者接下來將會對poj上出現過的這類題目做乙個總結,並介紹解決lis問題的兩個常用 演算法 n 2 和 nlogn 問題描述 給出乙個序列a1,a2,a3,a4,a5,a6,a7.an,求它的乙個子串行 設為s1...