Wavio Sequence UVA - 10534

最长上升子序列
题目描述:给了一个定义的序列Wavio,该序列的定义是:长度为2*n + 1,前n+1个数是严格递增的,后n+1个数是严格递减的,且相邻两个数不重复。求最长的Wavio序列的长度。
解题分析:数据量是10000,显然n*n的算法行不通,必须得用n*logn的算法。在本题中我的解法是,正序求最长上升子序列,逆序再求一遍,分别记录上升序列的最小下标,算完两个序列后,只要判断两个上升序列没有交差,那这个序列就是Waviox序列,更新最大值即可。在此处不用判断两个上升序列的最大值是否相等,因为如若不等,总可以让其中一个大的上升序列的最大值来替换小的那个上升序列的最大值。例如序列是1 2 4 7 和 9 8 2 1 ,只需要让第一个序列的最大值变为9就可以满足是Wavio序列了,前提是两个序列没有交叉。判断两个序列没有交叉就是判断的这两个序列的最大值的最小下标和是否>= N,如果不,则不交叉。
代码如下:

手写二分查找版

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 10000 + 10;
int num[maxn];
int dp1[maxn];
int dp2[maxn];
int index1[maxn];
int index2[maxn];

int bin_s(int t,int len,int * dp)
{
    int l = 0,r = len + 1;
    int ans;
    while(r - l > 1)
    {
        int mid = (l + r) / 2;
        if(dp[mid] >= t)
        {
            r = mid;
            ans = mid;
        }
        else
        {
            l = mid;
        }
    }
    return ans;
}

int main()
{
    int N;
    while(scanf("%d",&N)!=EOF)
    {
        for(int i = 0; i < N; i++)
        {
            scanf("%d",&num[i]);
        }
        memset(dp1,0x3f,sizeof(dp1));
        memset(dp2,0x3f,sizeof(dp2));
        int len = 1;
        dp1[1] = num[0];
        index1[len] = 0;
        for(int i = 1; i < N; i++)
        {
            if(num[i] > dp1[len])
            {
                dp1[++len] = num[i];
                index1[len] = i;
            }
            else
            {
                int t = bin_s(num[i],len,dp1);
                dp1[t] = num[i];
            }
        }
        reverse(num,num + N);
        len = 1;
        dp2[1] = num[0];
        index2[len] = 0;
        for(int i = 1; i < N; i++)
        {
            if(num[i] > dp2[len])
            {
                dp2[++len] = num[i];
                index2[len] = i;
            }
            else
            {
                int t = bin_s(num[i],len,dp2);
                dp2[t] = num[i];
            }
        }
        int ans = -1;
        for(int i = 1; i <= N; i++)
        {
            if(dp1[i] == INF ||dp2[i] == INF) continue;
            if(index1[i] + index2[i] >= N) continue;
            ans = max(ans,i);
        }
        cout << 2 * ans - 1 << endl;
    }
    return 0;
}
lower_bound版
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 10000 + 10;
int num[maxn];
int dp1[maxn];
int dp2[maxn];
int index1[maxn];
int index2[maxn];

int main()
{
    int N;
    while(scanf("%d",&N)!=EOF)
    {
        for(int i = 0; i < N; i++)
        {
            scanf("%d",&num[i]);
        }
        memset(dp1,0x3f,sizeof(dp1));
        memset(dp2,0x3f,sizeof(dp2));
        for(int i = 0; i < N; i++)
        {
            int t  =  lower_bound(dp1,dp1 + N,num[i]) - dp1;
            if(dp1[t] == INF) index1[t] = i;
            dp1[t] = num[i];
        }
        reverse(num,num + N);
        for(int i = 0; i < N; i++)
        {
            int t  =  lower_bound(dp2,dp2 + N,num[i]) - dp2;
            if(dp2[t] == INF) index2[t] = i;
            dp2[t] = num[i];
        }
        int ans = -1;
        for(int i = 0; i < N; i++)
        {
            if(dp1[i] == INF ||dp2[i] == INF) continue;
            if(index1[i] + index2[i] >= N) continue;
            ans = max(ans,i + 1);
        }
        cout << 2 * ans - 1 << endl;
    }
    return 0;
}

全部评论

相关推荐

06-10 23:36
已编辑
首都经济贸易大学 C++
点赞 评论 收藏
分享
牛客刘北:如果暑期实习是27届的话,你要晚一年才会毕业,企业为什么会等你呢?要搞清时间逻辑呀!27届现在实习只能是在暑假实习,这是日常实习,不是暑期实习。所以多去投日常实习吧,暑期实习肯定不会要你的
点赞 评论 收藏
分享
就前几天旅游的时候,打开抖音就经常刷到这类视频:以前是高学历学生、老师、主持人,现在做着团播、擦边主播的工作,以及那些经过精心包装的“职业转型”故事——从铺天盖地的VLOG到所谓的“04年夜场工作日记”,这些内容在初中升学、高考放榜等关键时间节点持续发酵。可以说非常直接且精准地在潜移默化地影响着心智尚未成熟的青少年,使其对特殊行业逐渐脱敏。那我就想问了:某些传播公司、平台运营者甚至某些夜场的老板,你们究竟在传递怎样的价值观?点开那些视频,评论区里也是呈现明显的两极分化:一种是​​经济下行论​​:“现在就业市场已经艰难到这种程度了吗?”​​一种是事实反驳派​​:这些创作者往往拥有名校背景,从事着...
牛客刘北:被环境教育的,为了能拿到足够的钱养活自己,不甘心也得甘心,现在的短视频传播的思想的确很扭曲,但是很明显,互联网玩上一年你就能全款提A6,但你全心全意不吃不喝工作一年未必能提A6,但是在高考中考出现这个的确很扭曲,在向大家传播“不上学,玩互联网也可以轻松年入百万”,不是人变了,是社会在变
预测一下26届秋招形势
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务