本文將會用幾道模板題來試著說明最長上公升子串行該如何操作。
二、最長上公升子串行ii
三、合唱隊形
題目鏈結
給定乙個長度為n的數列,求數值嚴格單調遞增的子串行的長度最長是多少。
輸入格式
第一行包含整數n。
第二行包含n個整數,表示完整序列。
輸出格式
輸出乙個整數,表示最大長度。
資料範圍
1≤n≤1000,
−109≤數列中的數≤109
dp思路
(1)狀態表示:f[i]一維陣列便可表示 所有以第 i 個數結尾的上公升子串行長度的最大值。
(2)狀態計算:以倒數第二個數是誰考慮(最後乙個數是a[i]),
j = 0, 1, 2…, i - 1, 且a[i] > a[j] :f[i] = max( f[j] + 1 )
時間複雜度:狀態數量 * 計算乙個花的時間, o(n ^ 2)
#include
#include
using namespace std;
const
int n =
1010
;int arr[n]
, f[n]
;int
main
(void)}
}int res =0;
for(
int i =
1; i <= n; i ++
) res =
max(res, f[i]);
cout << res << endl;
return0;
}
資料範圍十萬, 比上道題的範圍更大,上述題解會超時
題目鏈結
給定乙個長度為n的數列,求數值嚴格單調遞增的子串行的長度最長是多少。
輸入格式
第一行包含整數n。
第二行包含n個整數,表示完整序列。
輸出格式
輸出乙個整數,表示最大長度。
資料範圍
1≤n≤100000,
−109≤數列中的數≤109
舉例: 3 1 2 1 8 5 6
3 1 中, 如果後邊的數能接在3 後邊(上公升子串行),那麼一定能接在1後,3 > 1 我們沒有必要存 3 了
** 相同長度的子串行,我們只需要存乙個結尾最小的即可 **
由上述可證: 子串行越長,結尾最小值 越大。(單調遞增)
a[i]應該接到(小於a[i]的最大數的結尾那—>二分來實現)如:插到了長度為4的那裡,那我們需要更新長度為5結尾的最小值
#include
#include
using namespace std;
const
int n =
100010
;int n;
int a[n]
, q[n]
;//q儲存不同長度子串行的結尾的最小值
intmain()
// r找的是可以接在某個長度的後邊, q[r] 是小於a[i]的最後乙個數
len =
max(len, l +1)
;//更新最大值
q[l +1]
= a[i]
;//讓 r + 1長度最後乙個最小值的更新的再小一些
} cout << len << endl;
}
#include
#include
#include
using namespace std;
intmain
(void
) cout << stk.
size()
<< endl;
return0;
}/*例 n: 7
arr : 3 1 2 1 8 5 6
stk : 3
1 比 3 小
stk : 1
2 比 1 大
stk : 1 2
1 比 2 小
stk : 1 2
8 比 2 大
stk : 1 2 8
5 比 8 小
stk : 1 2 5
6 比 5 大
stk : 1 2 5 6
stk 的長度就是最長遞增子串行的長度
*/
題目鏈結
n位同學站成一排,**老師要請其中的(n-k)位同學出列,使得剩下的k位同學排成合唱隊形。
合唱隊形是指這樣的一種隊形:設k位同學從左到右依次編號為1,2…,k,他們的身高分別為t1,t2,…,tk, 則他們的身高滿足t1<…ti+1>…>tk(1≤i≤k)。
你的任務是,已知所有n位同學的身高,計算最少需要幾位同學出列,可以使得剩下的同學排成合唱隊形。
輸入格式
輸入的第一行是乙個整數n,表示同學的總數。
第二行有n個整數,用空格分隔,第i個整數ti是第i位同學的身高(厘公尺)。
輸出格式
輸出包括一行,這一行只包含乙個整數,就是最少需要幾位同學出列。
資料範圍
2≤n≤100,
130≤ti≤230
假設最優解的中心是第 ii 個人,則 t1,t2,…,tit1,t2,…,ti 一定是以 titi 結尾的最長上公升子串行。
同理,tk,tk−1,…,titk,tk−1,…,ti 也一定是以 titi 結尾的最長上公升子串行。
因此可以先預處理出:
從前往後以每個點結尾的最長上公升子串行長度 f[i];
從後往前以每個點結尾的最長上公升子串行長度 g[i];
那麼以 kk 為中心的最大長度就是 f[k] + g[k] - 1,遍歷 k = 1, 2, …, n 取最大值即為答案。
#include
#include
using namespace std;
const
int n =
110;
int n;
int f[n]
, g[n]
, w[n]
;int
main()
}//處理反向的
for(
int i = n; i ; i --)}
int res =0;
for(
int k =
1; k <= n; k ++
) res =
max(res, f[k]
+ g[k]-1
);cout << n - res << endl;
return0;
}
最長上公升子串行
問題描述 乙個數的序列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...
最長上公升子串行
最長上公升子串行問題 給出乙個由n個數組成的序列x 1.n 找出它的最長單調上公升子串行。即求最大的m和a1,a2 am,使得a1動態規劃求解思路分析 o n 2 經典的o n 2 的動態規劃演算法,設a i 表示序列中的第i個數,f i 表示從1到i這一段中以i結尾的最長上公升子串行的長度,初始時...