51Nod
来源:互联网 发布:mysql 查找第一条记录 编辑:程序博客网 时间:2024/05/17 03:34
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1153点击打开链接
1153 选择子序列
题目来源: Codility
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
长度为N的整数数组A,所有的数均不相同,假设下标从0开始。找到一个最长的数组B,B数组的长度为K,数值范围是0 - N - 1,记录的是A数组的下标。满足A[B[0]] > A[B[1]] > A[B[2]] >...A[B[K]],并且对任意连续的两项B[i]及B[i + 1],满足min(B[i],B[i + 1]) < j < max(B[i],B[i + 1]) 均有A[j] < A[B[i + 1]] ,求最大的K。例如:9, 10, 2, -1, 3, -5, 0, -3, 1, 12, 5, 8, -2, 6, 4。可以选出:12, 10, 3, 1, 0, -3。对应的下标为:9, 1, 4, 8, 6, 7(就是B数组),输出6。
Input
第1行:一个数N,表示A数组的长度。(1 <= N <= 50000)第2 - N + 1行:每行1个数对应A数组的元素Ai(0 < Ai < 10^9)
Output
输出B数组最长的长度K。
Input示例
159102-13-50-311258-264
Output示例
6
这道题网上的写法很多 单调栈 线段树 dfs。。
一开始想的是单调栈+贪心 单调栈左右扫一遍之后每次选取符合条件且范围最大的加入 但是存在像 1 2 10 3 4 12 9 8 7 6这样的数据 贪心会导致错误的选择
然后因为跟区间有关因此想到线段树
从小到大依次将每个数的范围的maxx值+1 维护每个区间的最大值
之所以从小到大 这样保证了后面加入的数一定能够包含比他小的数 并且选取的都是最优的路径+1
细想其实不难
#include <bits/stdc++.h>using namespace std;int a[50010];int la[50010];int ra[50010];struct xjy{ int sum; int num; bool operator < (const xjy &r)const { return sum > r.sum; }};struct xjyy{ int left; int right; int maxx;};xjyy tree[50010<<2];void build(int i,int left,int right){ if(left==right) { tree[i].left=left; tree[i].right=right; tree[i].maxx=0; return; } int mid=(left+right)>>1; build(i<<1,left,mid); build(i<<1|1,mid+1,right); tree[i].left=left; tree[i].right=right; tree[i].maxx=0;}void update(int i,int left,int right){ if(left==tree[i].left&&tree[i].right==right) { tree[i].maxx++; return; } int mid=(tree[i].left+tree[i].right)>>1; if(right<=mid) update(i<<1,left,right); else if(left>mid) update(i<<1|1,left,right); else { update(i<<1,left,mid); update(i<<1|1,mid+1,right); } tree[i].maxx=max(tree[i<<1].maxx,tree[i<<1|1].maxx);}priority_queue<xjy > q;int main(){ int n; cin >> n; for(int i=1;i<=n;i++) scanf("%d",&a[i]); stack <int > s; for(int i=1;i<=n;i++) { la[i]=i; if(s.empty()) { s.push(i); la[i]=1; } else { while(!s.empty()) { if(a[s.top()]<a[i]) { la[i]=la[s.top()]; s.pop(); } else { s.push(i); break; } } if(s.empty()) s.push(i); } } while(!s.empty()) s.pop(); for(int i=n;i>=1;i--) { ra[i]=i; if(s.empty()) { s.push(i); ra[i]=i; } else { while(!s.empty()) { if(a[s.top()]<a[i]) { ra[i]=ra[s.top()]; s.pop(); } else { s.push(i); break; } } if(s.empty()) s.push(i); } } build(1,1,n); for(int i=1;i<=n;i++) { xjy mid; mid.num=i; mid.sum=a[i]; q.push(mid); } while(!q.empty()) { xjy mid=q.top(); q.pop(); update(1,la[mid.num],ra[mid.num]); } cout << tree[1].maxx;}
阅读全文
0 0
- 51Nod
- 51Nod
- 51nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51nod
- c# Mutex 互斥操作
- 前端—第一天
- Centos7 升级python3,解决升级后不兼容问题
- HDU_1260_Tickets
- 避免界面设计的误区-从数据的三种状态谈界面设计
- 51Nod
- 刷题七
- 2017.9.5
- 1005. Spell It Right (20)
- Spring框架——事务处理(编程式和声明式)
- 优化MySQL Server
- swift语言-字符串
- 【索引】联合索引的执行
- anaconda升级sklearn版本