對於數列中的某個點:
求從它開始下降的最長子序列,這個序列將倒過來接到某點前面,成為最終的序列的前半段;
求從它開始上公升的最長子序列,這個序列將倒過來接到某點後面,成為最終的序列的後半段;
最終答案為某個點兩種子串行長度的和再減去1(因為統計了兩次自己)
其餘的操作其實都可以省略。(無法更優)
#include
#include
#include
using
namespace std;
int a[
100001
],b[
100001
],ans[10]
[100001
],c[
100001];
int n,z,ans;
void
asdf
(int cs)
}int
main()
asdf(1
);//求某點開始下降的最長子序列,這個序列將倒過來接到某點前面
for(
int i =
1; i <= n;
++i)
b[i]
=-b[i]
;//反過來,方便計算
asdf(2
);//求某點開始上公升的最長子序列,這個序列將倒過來接到某點後面
//最終某點不變位置,
for(
int i =
1; i <= n;
++i)
ans =
max(ans[1]
[i]+ans[2]
[i]-
1, ans)
;//找出最大的
printf
("%d"
, ans)
;}
雙端佇列xLIS問題
有 n 個數 a i 他準備將他們依次插入乙個雙端佇列 每次可以在頭或尾插入乙個元素 最後將 整個佇列從尾到頭看成乙個序列,求出最長上公升子串行的長度 他想知道 l 的最大值是多少。很簡單,考慮乙個數,構造有它的最長上公升子串行 把比他小的放他前面,比他大的放它後面 比他小的最優的就是以某乙個比他小...
2020多校聯考 雙端佇列xLIS問題
觀察將乙個序列按一定方法加入到雙端佇列的性質。發現若直接在隊尾加入,則不會改變相對順序,而加入到隊頭的元素實際上是原序列的某個子串行再反過來。乾脆直接將原序列複製乙份到前面再反轉。那麼答案就是這個新序列的最長上公升子串行 考慮反轉過去後,前後對應相等的兩個元素不會同時出現在最長上公升序列中 用樹狀陣...
雙端佇列xLIS問題 棧 最長不下降序列
解題思路 通過推算可以發現,對於原數列的第i ii個數,一定是放在雙端佇列的中間,雙端佇列的左邊和右邊都為不下降序列 自動排除與答案無關的數 並且左邊和右邊的數在原數列中,都位於i的右邊 再加上雙端佇列插入元素的規律,又可以神奇地發現,雙端佇列右邊的數在原數列中的排列一樣,而左邊的數在原數列中是倒過...