hdu 5748(求解最长上升子序列的两种O(nlogn)姿势)
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=5748
树状数组:
/*
对于普通的LIS:
for(i):1~n LIS[i]=1;
if j<i and a[j]<a[i]
LIS[i]=LIS[j]+1
因此可知LIS转移需要两个条件
1.(j<i) 序号必须在i之前
2.(a[i]>a[j]) 值必须比a[i]小
利用树状数组的顺序操作:{查找的都是已经出现的,序号在前(满足条件1)}
对于每一个值,查找它在数组中的排名,再去寻找小于它的排名的最大的LIS(满足条件2)
这里利用到了排名,因为这样可以最大限度地压缩C数组的空间
*/
#include <bits/stdc++.h>
using namespace std;
const int Max=1e5+;
int A[Max],V[Max],L[Max],C[Max],len;
int lowbit(int x) {return x&(-x);}
int Sum(int x) //求值小于等于x的LIS的最大值
{
int ret=;
while(x>)
{
if(C[x]>ret) ret=C[x];
x-=lowbit(x);
}
return ret;
}
void Add(int x,int d) //值大于等于x的LIS都改为LIS(x)
{
while(x<=len)
{
if(d>C[x]) C[x]=d;
x+=lowbit(x);
}
}
int main()
{
int T;
for(scanf("%d",&T);T;T--)
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&A[i]);
V[i]=A[i];
}
sort(V+,V++n);
len=unique(V+,V++n)-(V+);
memset(C,,sizeof(C));
int ans=,tmp,xu;
for(int i=;i<=n;i++)
{
xu=lower_bound(V+,V++len,A[i])-(V);
tmp=Sum(xu-)+;
L[i]=tmp;
Add(xu,tmp);
}
for(int i=;i<=n;i++)
{
if(i!=) printf(" ");
printf("%d",L[i]);
}
puts("");
}
return ;
}
dp+二分
/*
以dp[x]代表长度为x的LIS,且dp[x]==LIS长度为x的末尾值
每次都往前取dp[x]中最小的一个,当然在保证x尽可能地大的情况下
因为dp[x]是递增的,所以可以二分,l=1,r=当前最长的LIS
求得当前以小于当前a[i]的最长LIS
*/
#include <bits/stdc++.h>
using namespace std;
const int Max=1e5+;
int A[Max];
int dp[Max];
int LIS[Max];
void Get_lis(int n)
{
int i,j,l,r,mid,ans;
dp[]=A[];
int len=;
for(i=;i<=n;i++)
{
if(dp[len]<A[i]) j=++len;
else
{
l=;r=len;
ans=;
while(l<=r)
{
mid=(l+r)>>;
if(A[i]>dp[mid]&&A[i]<=dp[mid+])
{
ans=mid;break;
}
else if(A[i]>dp[mid]) l=mid+;
else r=mid-;
}
j=ans+;
}
dp[j]=A[i];
LIS[i]=j;
}
}
int main()
{
int T;
for(scanf("%d",&T);T;T--)
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&A[i]);
dp[i]=;
}
LIS[]=;
Get_lis(n);
for(int i=;i<=n;i++)
{
if(i!=) printf(" ");
printf("%d",LIS[i]);
}
puts("");
}
return ;
}
其实还有一种单调队列求最长上升子序列的方法,可是不能用来解这道题
/*
无解。。。
单调队列只能求出总体的LIS长度
*/
#include <bits/stdc++.h>
using namespace std;
const int Max=1e5+;
int que[Max];
int main()
{
int T;
for(scanf("%d",&T);T;T--)
{
int n,x,top=;
scanf("%d",&n);
for(int i=;i<n;i++)
{
scanf("%d",&x);
if(x>que[top]||top==)
{
que[++top]=x;
}
else
{
int l=,r=top,mid,ans;
ans=;
while(l<=r)
{
mid=l+(r-l)/;
if(que[mid]<x) l=mid+;
else r=mid-,ans=mid;
}
que[ans]=x;
}
}
cout<<top<<endl;
}
return ;
}
hdu 5748(求解最长上升子序列的两种O(nlogn)姿势)的更多相关文章
- 求解最长递增子序列(LIS) | 动态规划(DP)+ 二分法
1.题目描述 给定数组arr,返回arr的最长递增子序列. 2.举例 arr={2,1,5,3,6,4,8,9,7},返回的最长递增子序列为{1,3,4,8,9}. 3.解答 ...
- HDU 4681 String 最长公共子序列
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4681 题意: 给你a,b,c三个串,构造一个d串使得d是a,b的子序列,并且c是d的连续子串.求d最大 ...
- hdu 1025 dp 最长上升子序列
//Accepted 4372 KB 140 ms //dp 最长上升子序列 nlogn #include <cstdio> #include <cstring> #inclu ...
- hdu 5489(LIS最长上升子序列)
题意:一个含有n个元素的数组,删去k个连续数后,最长上升子序列 /*思路参考GoZy 思路: 4 2 3 [5 7 8] 9 11 ,括号表示要删掉的数, 所以 最长上升子序列 = ...
- hdu 5532(最长上升子序列)
Input The first line contains an integer T indicating the total number of test cases. Each test case ...
- Python动态规划求解最长递增子序列(LIS)
原始代码错误,移步博客查看O(N^2)及优化的O(N*logN)的实现:每天一道编程题--最长递增子序列
- 算法练习--- DP 求解最长上升子序列(LIS)
问题描写叙述: 对于2,5,3,1,9,4,6,8,7,找出最长上升子序列的个数 最长上升子序列定义: 对于i<j i,j∈a[0...n] 满足a[i]<a[j] 1. 找出DP公式:d ...
- HDU 1159.Common Subsequence-最长公共子序列(LCS)
Common Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- 最长上升子序列算法(n^2 及 nlogn) (LIS) POJ2533Longest Ordered Subsequence
问题描述: 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, ..., aN),我们可以得到一些上升的子序列 ...
随机推荐
- Python在安装第三方模块遇到的问题及解决办法
今天在安装第一个模块psutil的时候出现了以下问题: 1.找不到Python.h文件 解决办法:重新安装python环境:sudo apt-get install python-dev 说明:网上有 ...
- 【转载】C++ function、bind和lambda表达式
本篇随笔为转载,原贴地址:C++ function.bind和lambda表达式. 本文是C++0x系列的第四篇,主要是内容是C++0x中新增的lambda表达式, function对象和bind机制 ...
- win7,win8.1下hosts文件无法修改的快速解决办法
一,找到C:\Windows\System32\drivers\etc,下hosts文件复制一份到桌面: 二,使用notepad++或其他编辑器修改桌面复制出来的那份HOSTS: 三,将修改后的文件复 ...
- 十步图解CSS的position
CSS的positon,我想做为一个Web制作者来说都有碰到过,但至于对其是否真正的了解呢?那我就不也说了,至少我自己并不非常的了解其内核的运行.今天在Learn CSS Positioning in ...
- (转载)自定义 setDateFormat 显示格式
转自 http://blog.sina.com.cn/s/blog_67b27b60010130mr.html -(NSString *)getStringFromDate:(NSDate *)aDa ...
- expdp\impdp及exp\imp
数据泵文件 expdp介绍 EXPDP命令行选项1. ATTACH该选项用于在客户会话与已存在导出作用之间建立关联.语法如下ATTACH=[schema_name.]job_nameSchema_na ...
- Oracle SQL优化一(常见方法)
1.表访问方式优化: a)普通表优先“Index Lookup 索引扫描”,避免全表扫描 大多数场景下,通过“Index Lookup 索引扫描”要比“Full Table Scan (FTS) 全表 ...
- 开发中用到的开源框架汇总(Updating)
SuperWebSocket SuperSocket NPOI 官网:http://npoi.codeplex.com/ 实例讲解:http://www.cnblogs.com/yutian/p/52 ...
- Selenium2+python自动化21-TXT数据参数化
前言 在17篇我们讲了excel数据的参数化,有人问了txt数据的参数化该怎么办呢,下面小编为你带你txt数据参数化的讲解 一.以百度搜索为例,自动搜索五次不同的关键字.输入的数据不同从而引 ...
- UILabel的常用属性
UILabel常用属性1——实例化和设置文字 // 实例化UILabel并指定其边框 UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake ...