POJ 1631 Bridging signals(LIS O(nlogn)算法)
Description

A typical situation is schematically depicted in figure 1. The ports of the two functional blocks are numbered from 1 to p, from top to bottom. The signal mapping is described by a permutation of the numbers 1 to p in the form of a list of p unique numbers in the range 1 to p, in which the i:th number specifies which port on the right side should be connected to the i:th port on the left side.Two signals cross if and only if the straight lines connecting the two ports of each pair do.
Input
Output
Sample Input
4
6
4
2
6
3
1
5
10
2
3
4
5
6
7
8
9
10
1
8
8
7
6
5
4
3
2
1
9
5
8
9
2
3
1
7
4
6
Sample Output
3
9
1
4 题目大意:求最长上升子序列,序列长度最大为40000。 分析:如果用一般的LIS算法,时间复杂度高达n^2。这里引用《入门经典》复杂度为O(nlogn)的方法。
假设已经计算出的两个状态 a 和 b 满足Aa < Bb 且d(a)==d(b),则对于后续所有状态 i(即i>a且i>b)来说,a并不会比b差——如果b满足Ab < Ai的条件,a也满足,且二者的d值相同;但反过来却不一定了。换句话说,如果我们只保留a,一定不会丢失最优解。
这样,对于相同的d值,只需要保留A最小的一个。我们用g(i)表示d值为i的最小状态编号。根据上述推理证明
g(1)<=g(2)<=g(3)<=...<=g(n)
上述的g值是动态改变的。对于一个给定的状态i,我们只考虑在i之前已经计算过的状态j(即j<i)。在给定状态i时可以用二分查找得到满足g(k)>=Ai的第一个下标k,则d(i)=k,此时Ai<g(k),而d(i)=k,所以更新g(k)=Ai。(话说看的不是很明白)
for(i=1; i<=n; i++) g[i] = INF;
for(i=0; i<n; i++)
{
int k = lower_bound(g+1,g+n+1,A[i]) - g;
d[i]=k;
g[k] = A[i];
}
代码如下:
# include<cstdio>
# include<iostream>
# include<algorithm>
using namespace std;
# define INF 0xffffff
int n;
int g[],A[]; int main()
{
int i,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=; i<n; i++)
scanf("%d",&A[i]);
int ans = ;
for(i=; i<=n; i++) g[i] = INF;
for(i=; i<n; i++)
{
int k = lower_bound(g+,g+n+,A[i]) - g;
g[k] = A[i];
if(k>ans)
ans = k;
}
printf("%d\n",ans);
}
return ;
}
LIS nlogn算法大罗列!
网上有这一方面的总结 //n是原序列长度,a[]是原序列,D是a[]的值域大小 1. f[i]表示a[i]结尾的LIS长度,f[i] = max{f[j]}+1 : a[j]<a[i] 1.1 维护一个以a的值为下标,以f的值为值的树状数组优化转移。O(n log D) 1.2 g[x]表示长度为x的所有LIS中最小的末尾的值,可证g[x]单调递增,二分查找转移。O(n log n) 1.3 维护一个“最优”的LIS q,每次将q关于a[i]的lower_bound更新为a[i],同时转移。O(n log n) 1.2代码如下:
#include <iostream>
using namespace std; int a[];
int dp[];
int b[], blen;
int n; int main() {
int ca,i;
scanf("%d", &ca);
while (ca--) {
scanf("%d", &n);
for (i = ; i <= n; ++i) {
scanf("%d", a+i);
}
memset(b,,sizeof(b));
memset(dp,,sizeof(dp)); int left, right, mid;
blen = ;
int res = ;
for (i = ; i <= n; ++i) {
left = ;
right = blen;
int num = a[i];
while (left <= right) {
mid = (left + right)/;
if (b[mid] < a[i]) {
left = mid + ;
}
else {
right = mid - ;
}
}
dp[i] = left;
b[left] = a[i];
if (blen < left)
blen = left;
if (res < dp[i])
res = dp[i];
}
printf("%d\n", res);
}
return ;
}
POJ 1631 Bridging signals(LIS O(nlogn)算法)的更多相关文章
- POJ 1631 Bridging signals (LIS:最长上升子序列)
题意:给你一个长为n(n<=40000)的整数序列, 要你求出该序列的最长上升子序列LIS. 思路:要求(nlogn)解法 令g[i]==x表示当前遍历到的长度为i的所有最长上升子序列中的最小序 ...
- POJ 1631 Bridging signals(LIS 二分法 高速方法)
Language: Default Bridging signals Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1076 ...
- OpenJudge/Poj 1631 Bridging signals
1.链接地址: http://poj.org/problem?id=1631 http://bailian.openjudge.cn/practice/1631 2.题目: Bridging sign ...
- POJ 1631 Bridging signals
Bridging signals Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9441 Accepted: 5166 ...
- poj 1631 Bridging signals (二分||DP||最长递增子序列)
Bridging signals Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9234 Accepted: 5037 ...
- POJ 1631 Bridging signals(LIS的等价表述)
把左边固定,看右边,要求线不相交,编号满足单调性,其实是LIS的等价表述. (如果编号是乱的也可以把它有序化就像Uva 10635 Prince and Princess那样 O(nlogn) #in ...
- Poj 1631 Bridging signals(二分+DP 解 LIS)
题意:题目很难懂,题意很简单,求最长递增子序列LIS. 分析:本题的最大数据40000,多个case.用基础的O(N^2)动态规划求解是超时,采用O(n*log2n)的二分查找加速的改进型DP后AC了 ...
- POJ - 1631 Bridging signals(最长上升子序列---LIS)
题意:左右各n个端口,已知n组线路,要求切除最少的线路,使剩下的线路各不相交,按照左端口递增的顺序输入. 分析: 1.设左端口为l,右端口为r,因为左端口递增输入,l[i] < l[j](i & ...
- POJ 1631 Bridging signals & 2533 Longest Ordered Subsequence
两个都是最长上升子序列,所以就放一起了 1631 因为长度为40000,所以要用O(nlogn)的算法,其实就是另用一个数组c来存储当前最长子序列每一位的最小值,然后二分查找当前值在其中的位置:如果当 ...
随机推荐
- JavaScript高级程序设计46.pdf
鼠标按钮 只有在主鼠标按钮被单击(或键盘回车键被按下)是才会触发click事件,对于mousedown和mouseup事件,其event对象存在一个button属性,表示按下或者释放按钮.DOM的bu ...
- .net常見面試題(四)
1. .Net.C#.VisualStudio之间的关系是什么? .Net一般指的是.Net Framework,提供了基础的.Net类,这些类可以被任何一种.Net编程语言调用,.Net Frame ...
- usaco 奶牛集会 && 奶牛抗议
奶牛集会 Description 约翰家的N头奶牛每年都会参加“哞哞大会” .哞哞大会是世界奶牛界的盛事.集会上 的活动很多,比如堆干草,跨栅栏,摸牛仔的屁股等等.当然,哞哞大叫肯定也包括在内. 奶牛 ...
- __attribute__机制介绍 (转)
1. __attribute__ GNU C的一大特色(却不被初学者所知)就是__attribute__机制. __attribute__可以设置函数属性(Function Attribute).变量 ...
- Altium Designer6打印PCB 设置
1.File-->Page Setup Printer Paper一栏是打印纸的设置,不再罗嗦. 主要是Scaling一栏:ScaleMode项选择:ScaledPrint ...
- php 生成mysql数据字典代码
由于项目开发用了比较多的表 ,为了快速获取数据字典,通过php代码的方式来获取表结构和表注释.代码如下: <?php /** * 生成mysql数据字典 */ header ( "Co ...
- jetty之安装,配置,部署,运行
上篇文章中详解了关于什么是jetty,后续文章主要是介绍jetty的使用.本章介绍jetty环境的配置及部署war包. 1. 安装 1. 先下载一个jetty的压缩包,下载地址:http://www. ...
- android实习程序7——通话记录显示
下载SQLiteSpy.exe 打开模拟器5554 打开perspective,选择DDMS 打开Devices,确认存在emulator-5554 打开file Explorer 打开data文件夹 ...
- Socket程序中的Error#10054错误
近期使用winSock做的一个网络项目中,使用TCP+Socket连接编写的一个多线程的网络程序,功能是client负责不断地向server端发送数据,服务端负责接收数据.client是一个DLL,服 ...
- 用Gitosis搭建Git服务器(经典资料)
该文档介绍了用Gitosis自己搭建Git服务器,文章来自于<Git权威指南>一书的第31章,讲述详细易懂易操作,是搭建Git服务器绝好资料! 下载地址:http://download.c ...