HDU 1950 Bridging signals (LIS,O(nlogn))
2024-10-19 20:25:36
题意:
给一个数字序列,要求找到LIS,输出其长度。
思路:
扫一遍+二分,复杂度O(nlogn),空间复杂度O(n)。
具体方法:增加一个数组,用d[i]表示长度为 i 的递增子序列的最后一个元素,且该元素总是保持当前最小。初始化d[1]=A[i],当前LIS的长度len=1。从 2 to n,若A[i]>d[len],则d[++len]=A[i],否则,在数组d中找到A[i]应该插入的位置,代替掉那个第一个比它大的数字,比如d[k]<A[i]<=d[k+1],直接将A[i]代替掉d[k+1]。完成后len就是LIS的长度了。
#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 2147483647
#define LL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=;
const int mod=1e9+;
int a[N], d[N];
int* lower_( int *s,int *e,int val ) //二分找值,返回下标
{
int L=, R=e-s-, mid;
while(L<R)
{
mid=R-(R-L+)/; //保证至少减少1
if( s[mid]<val ) L=mid+;//至少增加1
else R=mid;
}
return &s[R];
} int main()
{
freopen("input.txt", "r", stdin);
int t, n, len;
cin>>t;
while(t--)
{
scanf("%d",&n);
for(int i=; i<=n; i++) scanf("%d",&a[i]);
len=;
d[len]=a[]; for( int i=; i<=n; i++ )
{
if( a[i]>d[len] ) d[++len]=a[i];
else *lower_(d+,d+len+,a[i])=a[i];
//else *lower_bound(d+1,d+len+1,a[i])=a[i]; 上一行代码可换成此行
}
printf("%d\n",len);
}
return ;
}
AC代码
最新文章
- 使用Github Pages建独立博客
- C扩展Python - official docs - defining new type
- 动态 SQL
- selenium2.0处理case实例(一)
- TestNG扩展
- PHPSTORM实用快捷键
- python操作redis-zset
- Difference between LINQ to SQL and LINQ to Entity(DataContext and DbContext)
- SSAS系列&mdash;&mdash;【04】多维数据(物理体系结构)
- 兼容不同浏览器的 CSS Hack 写法
- iOS回顾笔记(07) -- UITableView的使用和性能优化
- Android Foreground Service (前台服务)
- PV &; PVC - 每天5分钟玩转 Docker 容器技术(150)
- oracle 关于对时间操作的汇总
- PHP 闭包函数
- 我在MySQL免安装版使用过程中遇到的问题记录【二】
- NorFlash 学习
- SpringBoot - 添加定时任务
- CH 1402 - 后缀数组 - [字符串hash]
- TensorRT下安装pycuda
热门文章
- mysql : mysql 5.6.13 免安装版配置
- Game of Peace
- C#操作句柄
- Lightoj 1147【DP】
- UGUI(四)事件系统的封装
- hdu2147(yy)
- [Xcode 实际操作]八、网络与多线程-(23)多线程的同步与异步的区别
- [Xcode 实际操作]九、实用进阶-(21)使用“调试视图”查看各界面元素的层次顺序
- Android近场通信---NFC基础(二)(转)
- js+canvas(H5)实现小球移动小demo