1153 选择子序列
2015-07-07 19:00
375 查看
长度为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
Output
Input示例
Output示例
< 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示例
15 9 10 2 -1 3 -5 0 -3 1 12 5 8 -2 6 4
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; }
相关文章推荐
- ANE原生代码的调试(安卓)++flex通过ANE调试原生安卓代码
- hibernate基础之无法自动创建表总结
- grep与正则表达式
- PCB电路板元器件布局的一般原则
- 继承ActionBarActivity使用requestWindowFeature(Window.FEATURE_NO_TITLE)无效解决办法
- iOS-compile_debug-crash_record
- 基于pgrouting的任意两点间的最短路径查询函数二
- Cannot find module 'socket.io'
- 斯坦福《机器学习》Lesson4感想-------2、广义线性模型
- g++ GNU g++常用编译选项用法
- 自我介绍
- 探究LayoutInflater的inflate()方法
- Hadoop之HDFS文件操作
- 决策树
- LeetCode Integer To Roman & Roman To Int
- 一切成功源于积累——20150707 外汇经典之双杀 Double Kill 叁杀 欧美 市场気持ち的解读
- Android CoordinatorLayout + AppBarLayout(向上滚动隐藏指定的View)
- Centos 6/7 源码升级内核
- Java基础日记———多线程
- kettle菜鸟学习笔记3----kettle数据库连接错误及解决