總時間限制:
2000ms
記憶體限制:
65536kb
描述乙個數的序列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。
輸出最長上公升子串行的長度。
樣例輸入
7樣例輸出1 7 3 5 9 4 8
4下面放一下ac**
#include#define ll long long點選開啟摺疊**using
namespace
std;
const ll maxn=1000+10
;ll f[maxn];
//用來遞推的陣列
ll a[maxn];//
儲存輸入資料
intmain()
for(ll i=2;i<=n;i++)//
i=1時f[1]肯定等於1,所以從2開始
for(ll j=1;j<=i-1;j++)//
j代表列舉f[i]前面的所有可能
ll ans=f[1];//
為ans初定義
for(ll i=2;i<=n;i++)//
這裡的意思是找出f[i=1~n]的最大值
if(f[i]>ans)
ans=f[i];
cout
}
然後開始解釋一下這道題
我們建立乙個陣列f[maxn],
f陣列的意義是以a[i]結尾的序列能擁有的最大上公升長度
毫無疑問f[1]始終=1,然後我們對其他f[i]也都賦初始值為1,因為,如果f[i]就只包括a[i]乙個的話長度就是1呀
然後核心是狀態轉移方程
if(a[i]>a[j])//如果可以加在它後面,記住這裡的子串行是可以間斷的
f[i]=max(f[i],f[j]+1);
先說明j=1~i-1,因為a[i]只能拼接在它前面的序列嘛,所以j最大為i-1
解釋一下這段**:
if(a[i]>a[j])就是說可以拼接,因為符合上公升條件
然後f[i]=max(f[i],f[j]+1);這裡這段語句可能會執行幾次,所以有f[i]=max(f[i],....)這樣的東西,就是新的自己和舊的自己比較的意思,我們平時用的a=a+1,也是這樣,兩個a不一樣,a=a+1這個栗子是教練教我的,講的真好
然後f[i]=max(f[i],f[j]+1)的意思就是在前面已經判斷了可以拼接的基礎上,如果加在前面的f[j]序列上更長的話就f[i]=f[j]+1(+1的意思是相對於前面的f[j]長度又多了乙個,也就是多了a[i]),否則就f[i]=f[i]不變
最長上公升子串行 動態規劃 最長上公升子串行LIS
問題描述 最長上公升子串行 lis 給定長度為n的序列,從中選中乙個子串行,這個子串行需要單調遞增,請問最長子序列 lis 的長度?eg 1,5,2,3,11,7,9 則lis序列為 1,2,3,7,9 長度為5 設計狀態 記f x 為以a x 為結尾的lis長度,那麼lis max 那麼如何推到f...
最長上公升子串行 (動態規劃)
描述乙個數的序列 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 等等。...
最長上公升子串行(動態規劃)
描述 乙個數的序列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 等等。這...