先寫一下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...