题目背景

小强和阿米巴是好朋友。

题目描述

小强喜欢数列。有一天,他心血来潮,写下了三个长度均为n的数列。

阿米巴也很喜欢数列。但是他只喜欢其中一种,波动数列。

阿米巴把他的喜好告诉了小强。小强便打算找出这三个数列内的最长波动数列。

也就是说,如果我们将三个数列记做a[n][3],他必须要构造一个二元组序列:<p[i], q[i]>,使得对于任何 i>1 有:

p[i] > p[i-1]

若q[i] = 0,a[p[i]][q[i]] >= a[p[i-1]][q[i-1]]

若q[i] = 1,a[p[i]][q[i]] <= a[p[i-1]][q[i-1]]

若q[i] = 2,只要保持段内同向即可(就是对于连续的一段q[i]=2,要么都有a[p[i]][q[i]] >= a[p[i-1]][q[i-1]],要么都有a[p[i]][q[i]] <= a[p[i-1]][q[i-1]])。

小强希望这个二元组序列尽可能长。

提示:当q[i] != q[i-1]时,数列的增减性由q[i]而非q[i-1]决定。

清晰版题目描述

小强拿到一个3×n的数组,要在每一列选一个数(或者不选),满足以下条件:

1.如果在第一行选,那它必须大于等于上一个数

2.如果在第二行选,那么必须小于等于上一个数

3.如果在第三行选,对于连续的一段在第三行选的数,必须满足方向相同(都小于等于上一个数或者都大于等于上一个数)

输入输出格式

输入格式:

输入包含4行。

第一行一个数n,表示数列长度。

第2、3、4行,每行n个整数,分别表示三个数列。

输出格式:

输出仅包含一个整数,即最长波动数列的长度。

输入输出样例

输入样例#1:

6
1 2 3 6 5 4
5 4 3 7 8 9
1 2 3 6 5 4
输出样例#1:

6

说明

对于20%的数据,n <= 10, m <= 1000

对于60%的数据,n <= 1000, m <= 1000

对于100%的数据, n <= 100000, m <= 1000000000

其中m = max|a[i]|

样例解释:

取第三行1 2 3(增),然后取第1行6(增),然后取第三行5 4(减),长度为6。

我们考虑dp

f[i][1]表示第i位,选第1行

f[i][2]表示选第2行

f[i][3/4]表示第i位,选第3行,比上一个大/小

满足条件下:

f[i][1]=max(f[j][1~4])

f[i][2]=max(f[j][1~4])

f[i][3]=max(f[j][1,2,3])

f[i][4]=max(f[j][1,2,4])

这样时间复杂度为n^2

用线段树优化至nlogn

把所有a值离散,对应于4颗线段树

转移就变成了区间查询最大值,单点修改

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int c[][],n,sz,a[][],b[],num;
int f[][],s1,s2,s3,s4,ans;
void pushup(int rt,int p)
{
c[rt][p]=max(c[rt*][p],c[rt*+][p]);
}
int query(int rt,int l,int r,int L,int R,int p)
{
if (l>=L&&r<=R)
{
return c[rt][p];
}
int mid=(l+r)/,s=;
if (L<=mid) s=max(s,query(rt*,l,mid,L,R,p));
if (R>mid) s=max(s,query(rt*+,mid+,r,L,R,p));
return s;
}
void update(int rt,int l,int r,int x,int d,int p)
{
if (l==r)
{
c[rt][p]=d;
return;
}
int mid=(l+r)/;
if (x<=mid) update(rt*,l,mid,x,d,p);
else update(rt*+,mid+,r,x,d,p);
pushup(rt,p);
}
int main()
{
int i,j;
cin>>n;
for (j=; j<=; j++)
{
for (i=; i<=n; i++)
{
scanf("%d",&a[i][j]);
num++;
b[num]=a[i][j];
}
}
sort(b+,b+num+);
sz=unique(b+,b+num+)-(b+);
for (j=; j<=; j++)
{
for (i=; i<=n; i++)
a[i][j]=lower_bound(b+,b+sz+,a[i][j])-b;
}
for (i=; i<=n; i++)
a[i][]=a[i][];
for (i=; i<=n; i++)
{
s1=query(,,sz,,a[i][],);
s2=query(,,sz,,a[i][],);
s3=query(,,sz,,a[i][],);
s4=query(,,sz,,a[i][],);
f[i][]=max(f[i][],+max(s1,max(s2,max(s3,s4)))); s1=query(,,sz,a[i][],sz,);
s2=query(,,sz,a[i][],sz,);
s3=query(,,sz,a[i][],sz,);
s4=query(,,sz,a[i][],sz,);
f[i][]=max(f[i][],+max(s1,max(s2,max(s3,s4)))); s1=query(,,sz,,a[i][],);
s2=query(,,sz,,a[i][],);
s3=query(,,sz,,a[i][],);
f[i][]=max(f[i][],+max(s1,max(s2,s3))); s1=query(,,sz,a[i][],sz,);
s2=query(,,sz,a[i][],sz,);
s4=query(,,sz,a[i][],sz,);
f[i][]=max(f[i][],+max(s1,max(s2,s4))); update(,,sz,a[i][],f[i][],);
update(,,sz,a[i][],f[i][],);
update(,,sz,a[i][],f[i][],);
update(,,sz,a[i][],f[i][],);
ans=max(ans,max(f[i][],max(f[i][],max(f[i][],f[i][]))));
}
cout<<ans;
}

P3928 SAC E#1 - 一道简单题 Sequence2的更多相关文章

  1. 【Luogu】 P3928 SAC E#1 - 一道简单题 Sequence2

    [题目]洛谷10月月赛R1 提高组 [算法]递推DP+树状数组 [题解]列出DP递推方程,然后用树状数组维护前后缀和. #include<cstdio> #include<cstri ...

  2. 洛谷P3928 SAC E#1 - 一道简单题 Sequence2

    提交地址 题目背景 小强和阿米巴是好朋友. 题目描述 小强喜欢数列.有一天,他心血来潮,写下了三个长度均为n的数列. 阿米巴也很喜欢数列.但是他只喜欢其中一种,波动数列. 阿米巴把他的喜好告诉了小强. ...

  3. 又一道简单题&&Ladygod(两道思维水题)

    Ladygod Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit S ...

  4. CSU 1785: 又一道简单题

    1785: 又一道简单题 Submit Page   Summary   Time Limit: 5 Sec     Memory Limit: 128 Mb     Submitted: 602   ...

  5. 【洛谷十月月测】 P3927 SAC E#1 - 一道中档题 Factorial

    题目传送门:https://www.luogu.org/problemnew/show/P3927 题目大意:给你两个正整数n,k,求n!在k进制下末尾零的数量. 我们通过简单的数学分析,便可以发现, ...

  6. SAC E#1 - 一道神题 Sequence1

    题目背景 小强和阿米巴是好朋友. 题目描述 小强很喜欢数列.有一天,他心血来潮,写下了一个数列. 阿米巴也很喜欢数列.但是他只喜欢其中一种:波动数列. 一个长度为n的波动数列满足对于任何i(1 < ...

  7. SAC E#1 - 一道中档题 Factorial

    题目背景 SOL君(炉石主播)和SOL菌(完美信息教室讲师)是好朋友. 题目描述 SOL君很喜欢阶乘.而SOL菌很喜欢研究进制. 这一天,SOL君跟SOL菌炫技,随口算出了n的阶乘. SOL菌表示不服 ...

  8. 中南大学2018年ACM暑期集训前期训练题集(入门题) X: 又一道简单题

    简直智障,上一题V题,样例输出里面的“Case:”不要输出,到了这题又是要输出的了 #include<iostream> using namespace std; int num[1000 ...

  9. [洛谷3930]SAC E#1 - 一道大水题 Knight

    Description 他们经常在一起玩一个游戏,不,不是星际争霸,是国际象棋.毒奶色觉得F91是一只鸡.他在一个n×n的棋盘上用黑色的城堡(车).骑士(马).主教(象).皇后(副).国王(帅).士兵 ...

随机推荐

  1. 每日冲刺报告——Day1(Java-Team)

    第一天报告(11.2  周四) 团队:Java-Team 成员: 章辉宇(284) 吴政楠(286) 陈阳(PM:288) 韩华颂(142) 胡志权(143) github地址:https://git ...

  2. Week03-面向对象入门

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词,如类.对象.封装等 类 对象 封装 继承 覆盖 重载 构造函数 static public private toString f ...

  3. 团队作业7——第二次项目冲刺(Beta版本计划及安排)

     Beta版本冲刺       需要改进完善的功能 1.寻找BUG.并解决问题 2.界面的优化 下一阶段新增的功能' 1.个人信息头像上传 2.头像裁剪功能 需要改进的团队分工 1.之前产品的主要工作 ...

  4. 201621123031 《Java程序设计》第6周学习总结

    作业06-接口.内部类 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 注1:关键词与内容不求多 ...

  5. python 归并排序

    def merge_sort(alist): if len(alist) <= 1: return alist # 二分分解 num = len(alist)/2 left = merge_so ...

  6. Flask 学习 七 用户认证

    使用werkzeug 实现密码散列 from werkzeug.security import generate_password_hash,check_password_hash class Use ...

  7. django + nginx + uwsgi + websocket

    最近使用django框架做了一个简单的聊天机器人demo, 开发的过程中使用了django自带的websocket模块,当使用django框架自带的wsgi服务去启动的话,没有什么问题.如果要使用uw ...

  8. Java 持久化之 --io流与序列化操作

    1)File类操作文件的属性 1.File类的常用方法 1. 文件的绝对完整路径:getAbsolutePath() 文件名:getName() 文件相对路径:getPath() 文件的上一级目录:g ...

  9. Spring Boot整合Spring Security

    Spring Boot对于该家族的框架支持良好,但是当中本人作为小白配置还是有一点点的小问题,这里分享一下.这个项目是使用之前发布的Spring Boot会员管理系统重新改装,将之前filter登录验 ...

  10. springboot字符集乱码

    入门扫盲:https://www.2cto.com/database/201701/584442.html 1.修改springweb类bug 2.数据库连接配置 3.数据库字符集 https://w ...