题目大意:给定一串数字序列,然后叫你删除连续一部分序列,然后使得剩下的序列中存在的连续的最大增长序列长度是多少 。 。
//
// main.cpp
// uva UVa1471 Defense Lines
//
// Created by XD on 15/8/14.
// Copyright (c) 2015年 XD. All rights reserved.
//
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<vector>
#include <string.h>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
using namespace std ;
const int maxn = 200010 ;
int f[maxn] ,g[maxn],a[maxn] ;
struct Cardidate
{
int a , g ;
Cardidate (int a , int g):a(a) , g(g){} ;
bool operator < (const Cardidate &n ) const{
return a < n.a ;
} ;
};
set<Cardidate> s ;
int max(int x , int y )
{
return x > y ?x :y ;
}
int main(int argc, const char * argv[]) {
int T ,n;
scanf("%d" ,&T) ;
while (T--) {
scanf("%d" ,&n) ;
for (int i = 0; i < n ; i++) {
scanf("%d" ,&a[i]) ;
}
if (n== 1) {
printf("1\n") ;continue ;
}
//设置f[i]
f[n-1] = 1;
for (int i = n-2; i >=0; i--) {
if (a[i] < a[i+1]) {
f[i] = f[i+1] + 1 ;
}
else f[i] = 1 ;
}
//设置g[i]
g[0] = 1 ;
for(int i = 1 ; i < n;i++ )
{
if (a[i] > a[i-1]) {
g[i] = g[i-1] + 1 ;
}
else{
g[i] = 1 ;
}
}
//查找答案
s.clear() ;
s.insert(Cardidate(a[0], g[0])) ;
int ans= 1 ;
for(int i = 1 ; i < n ;i++)
{
Cardidate c(a[i], g[i]);
set<Cardidate>::iterator it = s.lower_bound(c); // first one that is >= c
bool keep = true;
if(it != s.begin()) {
Cardidate last = *(--it); // (--it) points to the largest one that is < c
int len = f[i] + last.g;
ans = max(ans, len);
if(c.g <= last.g) keep = false;
}
if(keep) {
s.erase(c); // if c.a is already present, the old g must be <= c.g
s.insert(c);
it = s.find(c); // this is a bit cumbersome and slow but it's clear
it++;
while(it != s.end() && it->a > c.a && it->g <= c.g) s.erase(it++);
}
}
printf("%d\n" ,ans) ;
}
return 0;
}
961

被折叠的 条评论
为什么被折叠?



