关于最长单调不升子序列和最长单调上升子序列写法

本人巨懒就用了STL

lower_bound会找出序列中第一个大于等于x的数

upper_bound会找出序列中第一个大于x的数

对于N个数求最长单调不上升子序列,使用一个数组f[]存下

然后使用一个栈dq,存储不上升序列

把f中的每个元素挨个加到d里面

如果a[i] > d[len],在dq中找到第一个小于f[i]的数w,用f[i]代替

如果w在末尾,由于w < a[i],所以y后面能接的不如a[i]多,w让位给a[i]可以让序列更长

如果w不在末尾,那w本来就是死的,有什么挽救的必要吗(无   慈   悲)

有首古诗说的很有道理

西江月·证明

即得易见平凡,仿照上例显然。

留作习题答案略,读者自证不难。

反之亦然同理,推论自然成立,略去过程QED,由上可知证毕。

妙————啊————

最长单调上升子序列写法就是最长单调不升子序列倒过来

贴代码

#include <bits/stdc++.h>
using namespace std;
const int N =2333333;
int f[N],dp[N],dq[N];
int n,m,len=1,lem=1;
int main()
{
    while(cin>>f[++n]);
    n--;
    dp[1]=f[1];
    dq[1]=f[1];
    for(int i=2;i<=n;i++)
    {
        if(dq[len]>=f[i]) dq[++len]=f[i];
        else
        {
            int p=upper_bound(dq+1,dq+1+len,f[i],greater<int>())-dq;
            dq[p]=f[i];
        }
        if(dp[lem]<f[i]) dp[++lem]=f[i];
        else
        {
            int q=lower_bound(dp+1,dp+1+lem,f[i])-dp;
            dp[q]=f[i];

        }

    }
    cout<<len<<endl<<lem;
    return 0;
}

//
// Created by 菰冭 on 2020/2/3.
//

 

posted @ 2020-02-03 23:31  菰冭  阅读(432)  评论(1编辑  收藏  举报