最近一直在做《挑战程序设计竞赛》的练习题,感觉好多经典的题,都值得记录。

题意:给你t组数据,每组数组有n个数字,求每组的最长上升子序列的长度。

思路:由于n最大为40000,所以n*n的复杂度不够了,会超时。

   书上状态方程换成了d[i]——以长度为i+1的上升子序列中末尾元素的最小值。

   那么我们在遍历第i个元素时候,以这个元素为末尾元素的最长子序列也就是在d[i]中找到一个小于num[i]的最大值,然后在这个序列末尾加上num[i]

   显然,我们在查找时便可以利用二分搜索,从而把复杂度从原来的n变为了logn,总复杂度从n*n变成了nlogn

  

   d[i]已经保证了长度为i+1的上升子序列末尾元素的最小值,那么对于d[i+1]长度为i+2的子序列里面,要获得最长,自然就要从长度为i+1的子序列中,挑选末尾元素为最小的子序列后面添加元素。所以d[i+1] > d[i],d数组是一个递增的数组,所以就能用二分搜索了。

  lower_bound(d,d+n,num[i]); //默认数组d为上升数组,返回第一个大于等于num[i]的指针。
  lower_bound(d,d+n,num[i],greater<int>()); //表达数组d为下降数组,返回第一个小于等于num[i]的指针。

AC代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 40005;
const int INF = 0X3F3F3F3F;
int n,t,num[N],d[N];
//d[i] = 长度为i+1的上升子序列中末尾元素的最小值,不存在则INF
void solve()
{
for(int i = 0; i < n; i++)
d[i] = INF;
for(int i = 0; i < n; i++)
{
scanf("%d", num+i);
*lower_bound(d,d+n,num[i]) = num[i];
}
printf("%d\n", lower_bound(d,d+n,INF) - d);
}
int main()
{
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
solve();
}
return 0;
}

  

POJ 1631 Bridging signals DP(最长上升子序列)的更多相关文章

  1. POJ - 1631 Bridging signals(最长上升子序列---LIS)

    题意:左右各n个端口,已知n组线路,要求切除最少的线路,使剩下的线路各不相交,按照左端口递增的顺序输入. 分析: 1.设左端口为l,右端口为r,因为左端口递增输入,l[i] < l[j](i & ...

  2. POJ 1631 Bridging signals (LIS:最长上升子序列)

    题意:给你一个长为n(n<=40000)的整数序列, 要你求出该序列的最长上升子序列LIS. 思路:要求(nlogn)解法 令g[i]==x表示当前遍历到的长度为i的所有最长上升子序列中的最小序 ...

  3. poj 1631 Bridging signals (二分||DP||最长递增子序列)

    Bridging signals Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9234   Accepted: 5037 ...

  4. Poj 1631 Bridging signals(二分+DP 解 LIS)

    题意:题目很难懂,题意很简单,求最长递增子序列LIS. 分析:本题的最大数据40000,多个case.用基础的O(N^2)动态规划求解是超时,采用O(n*log2n)的二分查找加速的改进型DP后AC了 ...

  5. OpenJudge/Poj 1631 Bridging signals

    1.链接地址: http://poj.org/problem?id=1631 http://bailian.openjudge.cn/practice/1631 2.题目: Bridging sign ...

  6. POJ 1631 Bridging signals(LIS O(nlogn)算法)

    Bridging signals Description 'Oh no, they've done it again', cries the chief designer at the Waferla ...

  7. POJ 1631 Bridging signals

    Bridging signals Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9441   Accepted: 5166 ...

  8. POJ 1631 Bridging signals & 2533 Longest Ordered Subsequence

    两个都是最长上升子序列,所以就放一起了 1631 因为长度为40000,所以要用O(nlogn)的算法,其实就是另用一个数组c来存储当前最长子序列每一位的最小值,然后二分查找当前值在其中的位置:如果当 ...

  9. POJ 1631 Bridging signals(LIS 二分法 高速方法)

    Language: Default Bridging signals Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1076 ...

随机推荐

  1. Java常见内存溢出异常分析(OutOfMemoryError)

    原文转载自:http://my.oschina.net/sunchp/blog/369412 1.背景知识 1).JVM体系结构 2).JVM运行时数据区 JVM内存结构的相关可以参考: http:/ ...

  2. 马士兵Servlet&Jsp学习

    Servlet&JSP 1>http常见错误信息:  404--url地址找不找,  403--禁止访问  500--服务器内部错误  2>Servlet的生命周期:  *生命全过 ...

  3. (转)iOS7界面设计规范(8) - UI基础 - 术语和措辞

    讨厌周一,讨厌一周.今天中午交互组聚餐,却很开心:大家都是很厉害的人,你可以感到他们身上的能量,可以感到有些什么东西正在推着自己尽力向前走.这是一种很健康的状态,同时也很难得,自然越发需要珍惜.从无到 ...

  4. (转)iOS Wow体验 - 第六章 - 交互模型与创新的产品概念(2)

    本文是<iOS Wow Factor:Apps and UX Design Techniques for iPhone and iPad>第六章译文精选的第二部分,其余章节将陆续放出.上一 ...

  5. 一个不错的PPT,扁平化设计,开放资源,要的进来

    开了那么多的博客,没做啥资源贡献,今天共享一个不错的PPT模板.例如以下图所看到的,须要的话留下邮箱 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFp ...

  6. C++11 lambda 表达式

    C++11 新增了很多特性,lambda 表达式是其中之一,如果你想了解的 C++11 完整特性,建议去这里,这里,这里,还有这里看看.本文作为 5 月的最后一篇博客,将介绍 C++11 的 lamb ...

  7. Samba通过ad域进行认证并限制空间大小《转载》

    本文实现了samba服务被访问的时候通过windows域服务器进行用户名和密码验证;认证通过的用户可以自动分配500M的共享空间;在用户通过windows域登陆系统的时候可以自动把这块空间映射成一块硬 ...

  8. Linux目录结构及文件基础操作

    一.Linux目录结构 windows系统中主要以存储介质为主(磁盘). UNIX和Linux系统中主要是以目录为主(以树形目录结构的形式构建整个系统). 1. FHS(Filesystem Hier ...

  9. oracle之substr函数

    substr(字符串,截取开始位置,截取长度) //返回截取的字 substr(,) //返回结果为 'H' *从字符串第一个字符开始截取长度为1的字符串 substr(,) //返回结果为 'H' ...

  10. Entity Framework - Func引起的数据库全表查询

    原文:http://www.cnblogs.com/dudu/archive/2012/04/01/enitity_framework_func.html 使用 Entity Framework 最要 ...