動態規劃之最長上公升子串行模型

2021-10-08 14:13:16 字數 3766 閱讀 8487

## lis問題及其應用
模板

這裡給出貪心+二分(n log n),dp(n²)兩種做法。

//動態規劃o(n²)

#include

#include

using

namespace std;

int n;

const

int max=

1010

;int a[max]

;int dp[max]

;int

main()

int res=0;

for(

int i=

1;i<=n;i++

) res=

max(res,dp[i]);

cout

}

#include

#include

using

namespace std;

int n;

const

int max=

10010

;int a[max]

,t[max]

;int

main()

t[r+1]

=a[i]

; len=

max(len,r+1)

;}cout

}

雙向lis

#include

#include

#include

using

namespace std;

int dp[

1001];

int a[

1001];

intmain()

for(

int i=

1;i<=n;i++

) result=

max(result,dp[i]);

}for

(int i=n;i>=

1;i--

) result=

max(result,dp[i]);

}printf

("%d\n"

,result);}

return0;

}

爆搜+lis

思路:預處理出以每個點為結尾的lis,和以每個點為開頭的下降序列。再通過暴力列舉出每一種情況。

#include

#include

#include

using

namespace std;

int n;

const

int max=

1100

;int high[max]

,higher[max]

,lower[max]

,res=0;

intmain()

}for

(int i=n;i;i--)}

for(

int i=

1;i<=n;i++

) res=

max(res,higher[i]

+lower[i]-1

);cout

}

合唱隊形(爆搜+lis)

思路:要想剔除的人最少,就需要對留下的人最多。根據題意,每個佇列都會有乙個中間點。(這個點左邊的點比他小,右邊的點比他大),那麼我們先預處理出以每個點作為中間點時,比它小的點的個數和比他大的點的個數。用上一題的做法求出佇列中最多剩下的人數之後,再用n(總共的人數)-這個數 就是答案。

#include

#include

#include

using

namespace std;

int n;

const

int max=

110;

int a[max]

;int higher[max]

,lower[max]

;int

main()

for(

int i=n;i;i--

)int res=0;

for(

int i=

1;i<=n;i++

) res=

max(res,lower[i]

+higher[i]-1

);cout

}

友好城市 轉換題lis+sort

思路: 本題的做法是先按照其友好城市的座標sort一遍,再做一遍lis。 接下來說明為什麼要這麼做:

1.友好城市之間的線路不能交叉,就代表著兩個友好城市的座標必須同時單調遞增。

2.再加上要求最多的城市對數,很容易想到要使用最長上公升子串行。既然要兩者同時保持單調性(自然可以基於其友好城市對其進行排序,兩個城市同時lis應該也可以)。

3.最後一邊lis就是答案。

//經過這一題,要注意演算法題中單調性,無論是條件還是特性都十分重要。

#include

#include

using

namespace std;

typedef pair<

int,

int> pii;

int n;

const

int max=

5100

;int dp[max]

;pii a[max]

;int

main()

sort

(a+1

,a+n+1)

;int res=0;

for(

int i=

1;i<=n;i++

) res=

max(dp[i]

,res);}

cout

}

lisdp思想運用 最大上公升子串行和

//dp的思想和考慮方式和lis問題一樣。

#include

#include

using

namespace std;

int n;

const

int max=

10010

;int a[max]

,dp[max]

;int

main()

res=

max(res,dp[i]);

} cout

}

lis問題性質的探索 dilworth定理

//關於lis問題有乙個非常有趣的性質:把整個序列用其下降子串行填滿需要的上公升子串行數=該序列的最長上公升子串行。

(類似,用上公升子串行填滿就=最長下降子串行長度)

#include

#include

#include

using

namespace std;

const

int max=

10010

;int a[max]

,up[max]

,down[max]

;int

main()

res1=

max(up[i]

,res1)

; res2=

max(res2,down[i]);

} cout

}

動態規劃 之 最長上公升子串行

乙個數的序列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 等等。這些子串...

動態規劃之最長上公升子串行

北大郭煒老師講的能採用動態規劃求解問題的特點 1 問題具有最優子結構的性質 2 無後效性。實現動態規劃的三個步驟 1 講原問題分解為子問題 2 確定狀態以及初始狀態 邊界值 3 狀態轉移方程 人人為我 遞推型 第一步的子問題就是a i 為終點的最長上公升子串行。include includeusin...

動態規劃之最長上公升子串行

動態規劃指的是將乙個繁雜的問題分解成子問題之後,通過求解子問題的最優解,從而求得整體最優解。輸入資料 輸入的第一行是序列的長度n 1 n 1000 第一行給出序列的n個整數,這些整數的取值範圍在0 10000.輸出要求 最長上公升子串行的長度。輸入樣例 7 1 7 3 5 9 4 8 輸出樣例 範例...