動態規劃 單調子串行相關

2021-09-27 08:16:23 字數 2355 閱讀 6267

我們要區分一下子序列和子串。

簡單的來講就是子串行是可以不連續但必須保證與給定的原陣列相同的順序,

子串就是必須連續並且保證與給定的原陣列順序相同。

我們討論的主要是子串行。

ac code:

#include

#include

#include

#include

using namespace std;

const

int maxn =

1e5+10;

int arr[maxn]

;int b[maxn]

;//存的是最長長度 為陣列下標的 lis 的最小末尾

int maxx;

intbinary

(int k)

}return l;

}int

main()

else

}printf

("%d\n"

,maxx);}

}

③ 乙個序列的最長上公升子串行不一定是唯一的,所以我們要學會如何求解乙個序列的最長子序列的個數。

所以我們需要在最長上公升子串行的基礎上去再增加乙個 動態規劃 ,就是以 arr【i】結尾的 子串行裡有幾個長度為 dp[i]的 記為 num[i];

看乙個最長下降子串行的題目:poj-1952

這題目就是求解最長下降子串行的個數。

if (dp[i] == dp[j]+1) num[i]+= num[j];

if(dp[j]+1>dp[i]) sum[i]=sum[j];

意思就是如果dp 轉移之後,如果最長的長度相同證明有多種轉移方式,就把num加起來,如果是乙個新的轉移就直接等於 num【j】.這個時候如果資料是321321就會有很多種重複情況,這時就要去重,有兩個地方要去重,第乙個是在計算dp的值的時候,對於同乙個個數轉移過來的要去重,如32***x和3***2x這兩種,這時如果在3***2x 中間的***都沒有比2大的數那麼肯定是取前面的2,後面的2就可以去掉了。第二個是在計算sum的時候,一旦遇到相同的數,就要跳出迴圈,否則會重複計算,詳見**理解。

此題目參考部落格:大佬部落格

ac code

#include

#include

#include

#include

#include

using namespace std;

const

int maxn =

5e3+10;

int arr[maxn]

;int dp[maxn]

;//以arr[i]結尾的最長遞減子串行的長度。

int num[maxn]

;//以arr[i]結尾的最長的個數。

int vis[maxn]

;int

main()

int maxx=

0,sum=0;

for(

int i=

0;i)else}}

else}}

if(maxx)maxx=dp[i];}

for(

int i=

0;i)printf

("%d %d\n"

,maxx,sum);}

return0;

}

④ 將乙個序列分為x個不下降子串行,求最小的x。

可以轉化成求原序列的最長遞增子串行。

證明:因為x堆中每一堆的元素都是單調不增的,所以對於原序列的最長遞增子串行的每個元素在x 堆中每堆至多乙個元素 所以最長遞增子串行長度l的最大值 為 x ,

所以有 x > = l;

我們要求的 x 的最小值就是 l .

例題 : wooden sticks poj - 1065

ac code

/*這道題的要求其實是將所有stick分為x個不下降子串行( ai <= ai+1 ),然後問題歸結於求x的最小值。*/

#include

#include

#include

#include

using namespace std;

const

int maxn =

5e3+10;

struct node

}arr[maxn]

;int dp[maxn]

;int

main()

sort

(arr,arr+n)

;int maxx=0;

for(

int i=

0;imaxx=

max(maxx,dp[i]);

} cout<}}

最長單調子串行(動態規劃)

最長上公升子串行 longest increasing subsequence 簡稱lis,也有些情況求的是最長非降序子串行,二者區別就是序列中是否可以有相等的數。例如 對於序列 1,7,3,5,9,4,8 我們就會得到一些上公升的子串行,如 1,7,9 3,4,8 1,3,5,8 等等,而這些子串...

動態規劃 最長單調子串行問題

求乙個正整數序列的最長單調自增子序列,子串行不要求是連續的。例如 input 5 5 2 4 3 1 output 2 確定狀態轉移方程,設f i 是以a i 為結尾的最大值的子串行的長度,那麼 max 的最大值就是要的結果。所以轉移方程為 f i max 1 所以 可以為 void main vo...

線段樹維護單調子串行

顯然這樣的操作,區間無法直接合併 我們考慮o l ogn o logn o logn 的push uppushup pushup 首先左兒子的最長長度不會變,我們考慮遞迴右兒子下去,並令當前的max nmaxn maxn 為左兒子的max nmaxn maxn 1,如果當前pus huppushup...