NYOJ 214 最长上升子序列(二)
2016-05-06 21:22
232 查看
单调递增子序列(二)
时间限制:1000 ms | 内存限制:65535 KB描述
给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序列,并求出其长度。
如:1 9 10 5 11 2 13的最长单调递增子序列是1 9 10 11 13,长度为5。
输入有多组测试数据(<=7)
每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的下一行里有n个整数,表示数列中的所有元素.每个整形数中间用空格间隔开(0<n<=100000)。
数据以EOF结束 。
输入数据保证合法(全为int型整数)!
输出对于每组测试数据输出整形数列的最长递增子序列的长度,每个输出占一行。
样例输入
7 1 9 10 5 11 2 13 2 2 -1
样例输出
5 1
分析:看到这个题与 最长上升子序列(一)相似,于是就用了递推去做,但是超时,对时间要求高,所以想到了二分法去查找可以节省很多时间。
二分法查找
二分法查找其实就是折半查找,一种效率较高的查找方法。针对有需数组来查找的。
主要思想是:(设查找的数组期间为array[low, high])
(1)确定该期间的中间位置K
(2)将查找的值T与array[k]比较。若相等,查找成功返回此位置;否则确定新的查找区域,继续二分查找。区域确定如下:
a.array[k]>T 由数组的有序性可知array[k,k+1,……,high]>T;故新的区间为array[low,……,K-1]
b.array[k]<T 类似上面查找区间为array[k+1,……,high]。每一次查找与中间值比较,可以确定是否查找成功,不成功当前查找区间缩小一半。递归找,即可。
时间复杂度:O(log2n);
代码实现:
/// <summary>
/// 二分法查找
/// </summary>
/// <param name="array">目标数组(已经排序好了)</param>
/// <param name="a">查找的数</param>
/// <returns>目标数的索引</returns>
public int BinarySearch(int[] array, int T)
{
int low, high, mid;
low = 0;
high = array.Length - 1;
while (low <= high)
{
mid = (low + high) / 2;
if (array[mid] < T)
{
low = mid + 1;
}
else if (array[mid]>T)
{
high = mid - 1;
}
else
{
return mid;
}
}
return -1;
}
当然 二分法也可以用于排序,由兴趣的可以在网上查找资料。
#include<stdio.h> #include<string.h> int m[100010],a[100010]; int BSearch(int a[], int n, int t) { int low = 1; int high = n; while (low <= high) //结束条件 { int mid = (low + high) / 2; if (t == a[mid]) return mid; else if (t > a[mid]) low = mid + 1; else high = mid - 1; } return low; } int LIS_BSearch(int a[], int m[], int n) { int maxlen = 1; //最长上升子序列的长度 m[maxlen] = a[1]; int i; for (i = 2; i <= n; i++) { if (a[i] > m[maxlen]) m[++maxlen] = a[i]; else { int p = BSearch(m, maxlen, a[i]);//返回小于a[i]的最大值的位置p m[p] = a[i]; } } return maxlen; } int main() { int t; while(~ scanf("%d",&t)) // while(t--) { int i,j,n,l=0; memset(m,0,sizeof(m)); memset (a,0,sizeof(a)); // scanf("%d",&n); for(i=1; i<=t; i++) scanf("%d",&a[i]); l=LIS_BSearch(a,m,t); printf("%d\n",l); } return 0; }
相关文章推荐
- android camera使用ISO值录制视频
- static在C和C++里各代表什么含义
- 讲义六 java中的数组
- 网络请求库的代码迁移
- poj 2758 && BZOJ 2258 Checking the Text 文本校对
- 安装数据库找不到数据库引擎启动句柄
- hihoCoder挑战赛20解题报告
- 异常情况下的生命周期分析
- c++ primer 学习笔记(1): 第1-5章
- BZOJ-2820-YY的GCD-(Mobius反演)
- 设计模式之:适配器模式
- 字符串匹配——朴素算法Brute-Force(布鲁特-福斯算法)
- selenium 入门
- 总结那些背出来让人感觉666的基本概念
- runtime-对成员变量和属性的操作
- 0505--鲜花售卖网之“NABCD模型”
- python中的json的基本使用方法
- 计算日期c语言(结构体+函数+闰年判断)
- NYOJ 题目252 01字串
- poj 2318 TOYS(计算几何)