描述乙個數的序列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)等等。這些子串行中最長的長度是4,比如子串行(1, 3, 5, 8
).你的任務,就是對於給定的序列,求出最長上公升子串行的長度。輸入輸入的第一行是序列的長度n (
1<= n <= 1000
)。第二行給出序列中的n個整數,這些整數的取值範圍都在0到10000。輸出最長上公升子串行的長度。樣例輸入717
3594
8樣例輸出
4**northeastern europe
2002, far-eastern subregion 比賽試題
首先我們來定義下狀態 dp[i]:以ai為末尾的最長上公升子串行的長度
狀態轉移方程:dp[i] = 的最長上公升子串行。
為了方便起見,我們定義d(i) (i∈[1,n])來表示前i個數以a[i]結尾的最長上公升子串行長度。
前1個數 d(1)=1子串行為2
前2個數 7前面有2小於7 d(2)=d(1)+1=2 子串行為2 7前3個數 在1前面沒有比1更小的,1自身組成長度為1的子串行 d(3)=1子串行為1
前4個數 5前面有2小於5 d(4)=d(1)+1=2 子串行為2 5前5個數 6前面有2 5小於6 d(5)=d(4)+1=3 子串行為2 5 6前6個數 4前面有2小於4 d(6)=d(1)+1=2 子串行為2 4前7個數 3前面有2小於3 d(3)=d(1)+1=2 子串行為2 3前8個數 8前面有2 5 6小於8 d(8)=d(5)+1=4 子串行為2 5 6 8前9個數 9前面有2 5 6 8小於9 d(9)=d(8)+1=5 子串行為2 5 6 8 9d(i)=max 我們可以看出這9個數的lis為d(9)=5
核心**:
voidsolve() res =max(res, dp[i]);
}printf(
"%d\n
", res);
}
對狀態的定義只有一種嗎?當然不是
我們可以用完全不同的視角定義這個問題
狀態 dp[i]:長度為i+1的上公升子串行中末尾元素的最小值(不存在的話就是inf)
狀態轉移方程:dp[i] =
我們再舉乙個例子:有以下序列a=,求lis長度。我們定義乙個b[i]來儲存可能的排序序列,len為lis長度。我們依次把a[i]有序地放進b[i]裡。(為了方便,這時i的範圍就從1~n表示第i個數)
a[1]=3,把3放進dp[1],此時dp[1]=3,此時len=1,最小末尾是3
a[2]=1,因為1比3小,所以可以把dp[1]中的3替換為1,此時b[1]=1,此時len=1,最小末尾是1
a[3]=2,2大於1,就把2放進dp[2]=2,此時b=,len=2同理,a[4]=6,把6放進dp[3]=6,b=,len=3a[5]=4,4在2和6之間,比6小,可以把dp[3]替換為4,b=,len=3a[6]=5,dp[4]=5,dp=,len=4a[7]=10,dp[5]=10,b=,len=5a[8]=7,7在5和10之間,比10小,可以把dp[5]替換為7,b=,len=5
核心**( o(n2) ):
voidsolve()
}}
優化後的**( o(nlogn) ):
voidsolve()
printf(
"%d\n
", 1ower_bound(dp, dp+n, inf) -dp);
}
附:
lower_bound( )和upper_bound( )都是利用二分查詢的方法在乙個排好序的陣列中進行查詢的。
lower_bound():返回的是被查序列中第乙個大於等於查詢值的指標
upper_bound():返回的是被查序列中第乙個大於查詢值得指標
最長上公升子串行問題
網上一大堆,說說思路吧,以4 2 6 3 1 5為例 逐個讀入數字,4 此時可能的佇列長度為1,最大值為4 4 2 由於2 4,此時佇列長度為1,最大值為2 4 2 6 6 2,佇列有2個,乙個長度為1,最大為2,乙個長度為2,最大為6 4 2 6 3 3 6,3 2,佇列有2個,乙個長度為1,最大...
最長上公升子串行問題
題型 poj 1631 問題描述 給出乙個陣列,求最長上公升子串行的長度。方法一 時間複雜度n 1000 思路 邊輸入邊處理,每次往陣列裡存,就替換這個數 就是所謂的二分法 include include include include using namespace std int a 40000...
問題 A 最長上公升子串行
題目描述 乙個數列ai如果滿足條件a1 a2 an,那麼它是乙個有序的上公升數列。我們取數列 a1,a2,an 的任一子串行 ai1,ai2,aik 使得1 i1 i2 ik n。例如,數列 1,7,3,5,9,4,8 的有序上公升子串行,像 1,7 3,4,8 和許多其他的子串行。在所有的子串行中...