After the last war devastated your country, you - as the king of the land of Ardenia - decided it was
high time to improve the defense of your capital city. A part of your fortication is a line of mage
towers, starting near the city and continuing to the northern woods. Your advisors determined that the
quality of the defense depended only on one factor: the length of a longest contiguous tower sequence
of increasing heights. (They gave you a lengthy explanation, but the only thing you understood was
that it had something to do with ring energy bolts at enemy forces).
After some hard negotiations, it appeared that building new towers is out of question. Mages of
Ardenia have agreed to demolish some of their towers, though. You may demolish arbitrary number of
towers, but the mages enforced one condition: these towers have to be consecutive.
For example, if the heights of towers were, respectively, 5, 3, 4, 9, 2, 8, 6, 7, 1, then by demolishing
towers of heights 9, 2, and 8, the longest increasing sequence of consecutive towers is 3, 4, 6, 7.
Input
The input contains several test cases. The rst line of the input contains a positive integer Z 25,
denoting the number of test cases. Then Z test cases follow, each conforming to the format described
below.
The input instance consists of two lines. The rst one contains one positive integer n 2 105
denoting the number of towers. The second line contains n positive integers not larger than 109
separated by single spaces being the heights of the towers.
Output
For each test case, your program has to write an output conforming to the format described below.
You should output one line containing the length of a longest increasing sequence of consecutive
towers, achievable by demolishing some consecutive towers or no tower at all.

 #include<cstdio>
#include<set>
#include<cstring>
#define M(a) memset(a,0,sizeof(a))
using namespace std;
struct ele
{
int a,g;
bool operator < (const ele & x) const
{
return a<x.a;
}
}e1,e2;
set<ele> s;
set<ele>::iterator it;
int a[],f[],g[];
int main()
{
int i,j,k,m,n,p,q,x,y,z,t,ans;
bool b;
scanf("%d",&t);
while (t--)
{
M(a);
M(f);
M(g);
s.clear();
scanf("%d",&n);
for (i=;i<=n;i++)
scanf("%d",&a[i]);
for (i=n;i>=;i--)
if (a[i]<a[i+]) f[i]=f[i+]+;
else f[i]=;
for (i=;i<=n;i++)
if (a[i]>a[i-]) g[i]=g[i-]+;
else g[i]=;
e1.a=a[];
e1.g=g[];
s.insert(e1);
ans=;
for (i=;i<=n;i++)
{
e1.a=a[i];
e1.g=g[i];
it=s.lower_bound(e1);
b=;
if (it!=s.begin())
{
e2=*(--it);
if (f[i]+e2.g>ans) ans=f[i]+e2.g;
if (e1.g<=e2.g) b=;
}
if (b)
{
s.erase(e1);
s.insert(e1);
it=s.find(e1);
it++;
while (it!=s.end()&&(*it).a>e1.a&&(*it).g<=e1.g) s.erase(it++);
}
}
printf("%d\n",ans);
}
}

因为不太会写stl,所以照着标程边抄边改边理解。

对于每个元素求出以它开头和结尾的最长递增子序列长度f[i]和g[i],那么对于每一个确定的后端点i,只需要找到满足a[j]<a[i]的最大g[j]即可。

易知如果a[j']>a[j]且g[j']<=g[j],则j’一定没用,因为j不但比他容易用,还比他效果好。

用set存储所有满足条件的pair<a[j],g[j]>,按a排序【则g也一定有序】。对于每个i,用lower_bound找到第一个>=它的,也就找到了最后一个<它的。用其更新答案。

用i更新完ans之后,需要把i也插入set中,为后面的元素服务。先判断i是否要插入(也就是有没有比他好的,只需要和刚才找见的最后一个<它的比较即可),再看插入之后可以删掉哪些元素(也就是没有它好的,向他前面一个一个找)。

uva 1471 defence lines——yhx的更多相关文章

  1. UVa 1471 Defense Lines - 线段树 - 离散化

    题意是说给一个序列,删掉其中一段连续的子序列(貌似可以为空),使得新的序列中最长的连续递增子序列最长. 网上似乎最多的做法是二分查找优化,然而不会,只会值域线段树和离散化... 先预处理出所有的点所能 ...

  2. UVA - 1471 Defense Lines 树状数组/二分

                                  Defense Lines After the last war devastated your country, you - as the ...

  3. uva 1471 Defense Lines

    题意: 给一个长度为n(n <= 200000) 的序列,你删除一段连续的子序列,使得剩下的序列拼接起来,有一个最长的连续递增子序列 分析: 就是最长上升子序列的变形.需要加一个类似二分搜索就好 ...

  4. UVA - 1471 Defense Lines (set/bit/lis)

    紫薯例题+1. 题意:给你一个长度为n(n<=200000)的序列a[n],求删除一个连续子序列后的可能的最长连续上升子序列的长度. 首先对序列进行分段,每一段连续的子序列的元素递增,设L[i] ...

  5. UVA 1471 Defense Lines 防线 (LIS变形)

    给一个长度为n的序列,要求删除一个连续子序列,使剩下的序列有一个长度最大的连续递增子序列. 最简单的想法是枚举起点j和终点i,然后数一数,分别向前或向后能延伸的最长长度,记为g(i)和f(i).可以先 ...

  6. UVa 1471 Defense Lines (二分+set优化)

    题意:给定一个序列,然后让你删除一段连续的序列,使得剩下的序列中连续递增子序列最长. 析:如果暴力枚举那么时间复杂度肯定受不了,我们可以先进行预处理,f[i] 表示以 i 结尾的连续最长序列,g[i] ...

  7. Uva 1471 Defense Lines(LIS变形)

    题意: 给你一个数组,让你删除一个连续的子序列,使得剩下的序列中有最长上升子序列, 求出这个长度. 题解: 预处理:先求一个last[i],以a[i]为开始的合法最长上升子序列的长度.再求一个pre[ ...

  8. UVa 1471 (LIS变形) Defense Lines

    题意: 给出一个序列,删掉它的一个连续子序列(该子序列可以为空),使得剩下的序列有最长的连续严格递增子序列. 分析: 这个可以看作lrj的<训练指南>P62中讲到的LIS的O(nlogn) ...

  9. 【uva 1471】Defense Lines(算法效率--使用数据结构+部分枚举+类贪心)

    P.S.我完全一个字一个字敲出来的血泪史啊~~所以,没有附代码,也是可以理解的啦.OvO 题意:给一个长度为N(N≤200000)的序列,要删除一个连续子序列,使得剩下的序列中有一个长度最大的连续递增 ...

随机推荐

  1. MySQL SQL模式匹配

    MySQL提供标准的SQL模式匹配,SQL模式匹配允许你使用“_”匹配任何单个字符,而“%”匹配任意数目字符(包括零字符).. 关于SQL模式匹配:http://dev.mysql.com/doc/r ...

  2. php中的常用数组函数(三)(获取数组交集的函数们 array_intersect()、array_intersect_key()、array_intersect_assoc()、array_intersect_uassoc()、array_intersect_ukey())

    这5个获取交集的函数 有 5个对应的获取差集的函数.我是链接. array_intersect($arr1, $arr2); //获得数组同键值的交集 array_intersect_key($arr ...

  3. Natural language style method declaration and usages in programming languages

    More descriptive way to declare and use a method in programming languages At present, in most progra ...

  4. 「C语言」文件的概念与简单数据流的读写函数

    写完「C语言」单链表/双向链表的建立/遍历/插入/删除 后,如何将内存中的链表信息及时的保存到文件中,又能够及时的从文件中读取出来进行处理,便需要用到”文件“的相关知识点进行文件的输入.输出. 其实, ...

  5. android Adapter剖析理解

    UI控件都是跟Adapter(适配器)打交道的 Adapter: 是用来帮助控件填充数据的中间桥梁 (在开发中大多数Textview控件的内容是依靠数据库传递并显示的如:新闻类) Adapter: 将 ...

  6. Android使用默认样式创建View的几个姿势

    以下内容是分析安卓源码所得: 1: 使用默认样式创建View的方式, 源码文件 Button.Java  注:此文参考http://www.linzenews.com/ 中的内容所写,如侵删! 2: ...

  7. Math对象常用方法汇总

    前几天翻阅<JavaScript权威指南>,看到了Math对象,于是汇总了一下. Math对象不同于其他的对象,它可以说是一个公共数学类,里面有很多数学方法,用于各种数学运算,但是Math ...

  8. MapGIS转Shp文件的单位问题

    在MapGIS浏览查看一下数据,各种不习惯:用mapgis自带的转shp功能,属性表会出错:利用名为map2shp的试用版软件可将mapgis格式的数据较为良好转成shp格式.但经常会遇到一个单位问题 ...

  9. Log4net中的调错

    在使用log4net时,感觉最麻烦的就是配置文件了,为了使用方便,我不得不先准备好一个完整的配置文件方案,测试了输出到文本.控制台.windows事件.SQL Server数据库都没有问题,但输出到o ...

  10. [ html canvas getImageData Object.data.length ] canvas绘图属性 getImageData Object.data.length 属性讲解

    <!DOCTYPE html> <html lang='zh-cn'> <head> <title>Insert you title</title ...