1153 选择子序列
来源:互联网 发布:少年班人物原型知乎 编辑:程序博客网 时间:2024/06/05 18:00
长度为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
解题思路:首先应该找出所有的i和j,满足题目中要求的条件,i->j连一条有向边,最终得到的图是一个DAG,瞬间变成了求DAG的最长路,采用记忆花搜索的方法,如何高效的建图是解决本题的关键,待我建完图才发现我建图的过程中其实维护的是一个单调递减的队列,囧~~~~~
#include <cmath>#include <ctime>#include <cstdio>#include <cstdlib>#include <cstring>#include <cctype>#include <climits>#include <cassert>#include <iostream>#include <string>#include <vector>#include <deque>#include <queue>#include <stack>#include <list>#include <map>#include <set>#include <utility>#include <numeric>#include <algorithm>#include <functional>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;const ll INF = 0x3f3f3f3f3f3f3f3fLL;const double pi = acos(-1.0);const double eps = 1e-6;const int maxn = 50010;int arr[maxn];int dis[maxn];vector<int> g[maxn];deque<int> dq;void init() { while(!dq.empty()) dq.pop_back(); for(int i = 0; i < maxn; ++i) { g[i].clear(); } memset(dis, -1, sizeof(dis));}int dfs(int u) { if(dis[u] > 0) return dis[u]; int size = g[u].size(); if(size == 0) return dis[u] = 1; int maxd = -1; for(int i = 0; i < size; ++i) { int v = g[u][i]; maxd = max(maxd, dfs(v) + 1); } return dis[u] = maxd;}int main() { //freopen("aa.in", "r", stdin); int n; init(); scanf("%d", &n); for(int i = 0; i < n; ++i) { scanf("%d", &arr[i]); } int id = 0; while(id < n) { if(dq.empty()) { dq.push_back(id); } else { if(arr[dq.back()] < arr[id]) { while(!dq.empty() && arr[dq.back()] < arr[id]) { g[id].push_back(dq.back()); dq.pop_back(); } if(!dq.empty()) { g[dq.back()].push_back(id); } dq.push_back(id); } else { if(!dq.empty()) { g[dq.back()].push_back(id); } dq.push_back(id); } } ++id; } int ans = 0; for(int i = 0; i < n; ++i) { if(dis[i] == -1) { dfs(i); } ans = max(ans, dis[i]); } printf("%d\n", ans); return 0;}
0 0
- 1153 选择子序列
- 选择子序列(51nod-1153)
- 选择子序列
- 选择子序列
- 选择子序列 51Nod
- 51Nod-1153-选择子序列
- 51nod 1153 选择子序列 (好题)
- 51NOD1153 选择子序列 【分治法+RMQ水一发】
- 子序列
- 子序列
- 子序列。
- 子序列
- 子序列
- 子序列
- 子序列
- O(nlogn)的最长上升子序列并且记录所选择的数 模板
- 子序列、子串问题
- 最长公共子序列
- ActiveX 属性持久性 是否是测试环境判断
- iOS-compile_debug-crash_record
- 主流图片加载框架对比,及遇到的问题
- AVL Tree(平衡二叉树)
- ANE原生代码的调试(安卓)++flex通过ANE调试原生安卓代码
- 1153 选择子序列
- Mysql数据库备份和还原常用的命令
- 机器学习一些博客
- hello, world
- JavaScript之this用法详解
- NowCoder猜想---统计n以内的素数个数
- mysql中为用户设置密码的多种方法
- Yii2学习笔记(一):Yii的安装和使用
- TabLayout、ViewPager和Fragment的多页面滑动