这个博客说的已经很好了。http://blog.csdn.net/shuangde800/article/details/7474903

简单记录一下自己学的:

问题就是求一个数列最长上升子序列的长度。

如果子序列长度相同,那么末尾小的子序列更有可能成为最长的子序列。所以就用一个l数组存当子序列长度为len时最小的末尾元素。如果序列下一个值比l[len]大,说明上升子序列长度增加,那么l[len++]=a[i];如果是小,就想办法把它插入到了l数组中....

HDU 1950 说白了就是求lis:

 #include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
int a[maxn],l[maxn];
int len,n; int lis()
{
len=;
l[]=a[];
for (int i=;i<n;i++){
if(a[i]>l[len-])
l[len++]=a[i];
else
*lower_bound(l,l+len,a[i])=a[i];
}
return len;
} int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
for (int i=;i<n;i++)
cin>>a[i];
cout<<lis()<<endl;
}
return ;
}

这个是二分写法(感觉二分用的最广):

 #include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
int a[maxn],l[maxn];
int len,n; int bin_search(int key)
{
int left, right, mid;
left = , right = len;//应该是数据比较水,这样写是左闭右开区间查找,严格来说应该是right=len+1
while (left<right)
{
mid = (left + right) >> ;
if (l[mid] >= key)
right = mid;
else left = mid + ;
}
return left;
} int lis()
{
len = ;
l[] = a[];
for (int i = ; i <= n; i++) {
if (a[i] > l[len])
l[++len] = a[i];
else {
int pos = bin_search(a[i]);
l[pos] = a[i];
}
}
return len;
} int main()
{
int T;
cin >> T;
while (T--)
{
cin >> n;
for (int i = ; i <= n; i++)
cin >> a[i];
cout << lis() << endl;
}
return ;
}

二分也可以这样写 (查找第一个大于或等于key的元素):

 int bin_search(int key)
{
while(left<=right)
{
mid=(left+right)>>;
if(l[mid]>=key)
right=mid-;
else left=mid+;
}
return left;
}

还有一种是用stl里的set写,原理和上面一样,感觉用的好精妙:

 #include<iostream>
#include<algorithm>
#include<set>
using namespace std;
const int MAXN = ;
set<int> st;
set<int>::iterator it;
int a[MAXN]; int main()
{
int T, n;
cin >> T;
while (T--)
{
st.clear();
cin >> n;
for (int i = ; i <= n; i++) {
cin >> a[i];
if (st.count(a[i])) continue;
st.insert(a[i]);
it = st.find(a[i]);
it++;
if (it != st.end())
st.erase(it);
}
cout << st.size() << endl;
}
return ;
}

当然,还有更精妙的:

 #include<iostream>
#include<algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = ;
int a[N],dp[N]; int main()
{
int T, n;
cin >> T;
while (T--)
{
cin >> n;
for (int i = ; i < n; i++) {
cin >> a[i]; dp[i] = INF;
}
for (int i = ; i < n; i++)
*lower_bound(dp, dp + n, a[i]) = a[i];
cout << lower_bound(dp, dp + n, INF) - dp << endl;
}
return ;
}

hdu 1950 最长上升子序列(lis) nlogn算法【dp】的更多相关文章

  1. AT2827 最长上升子序列LIS(nlogn的DP优化)

      题意翻译 给定一长度为n的数列,请在不改变原数列顺序的前提下,从中随机的取出一定数量的整数,并使这些整数构成单调上升序列. 输出这类单调上升序列的最大长度. 数据范围:1<=n<=10 ...

  2. hdu 5773 最长递增子序列 (nlogn)+贪心

    The All-purpose Zero Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  3. hdu 1950 最长上升子序列

    //Accepted 3540 KB 62 ms //dp 最长上升子序列 #include <cstdio> #include <cstring> #include < ...

  4. 最长上升子序列 LIS nlogn

    给出一个 1 ∼ n (n ≤ 10^5) 的排列 P 求其最长上升子序列长度 Input 第一行一个正整数n,表示序列中整数个数: 第二行是空格隔开的n个整数组成的序列. Output 最长上升子序 ...

  5. (转载)最长递增子序列 O(NlogN)算法

    原博文:传送门 最长递增子序列(Longest Increasing Subsequence) 下面我们简记为 LIS. 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则 ...

  6. 最长递增子序列 O(NlogN)算法

    转自:点击打开链接 最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS. 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个 ...

  7. 最长上升子序列O(nlogn)算法详解

    最长上升子序列 时间限制: 10 Sec   内存限制:128 MB 题目描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.我们想知道此时最长上升子 ...

  8. nlogn 求最长上升子序列 LIS

    最近在做单调队列,发现了最长上升子序列O(nlogn)的求法也有利用单调队列的思想. 最长递增子序列问题:在一列数中寻找一些数,这些数满足:任意两个数a[i]和a[j],若i<j,必有a[i]& ...

  9. 最长上升子序列 LIS(Longest Increasing Subsequence)

    引出: 问题描述:给出一个序列a1,a2,a3,a4,a5,a6,a7….an,求它的一个子序列(设为s1,s2,…sn),使得这个子序列满足这样的性质,s1<s2<s3<…< ...

随机推荐

  1. JavaScript数据存储和深浅拷贝实际运用

    JavaScript分两种数据类型.1.简单数据类型有:number, string, boolean, undefined和null当声明一个简单数据类型的变量时,在内存中会把数据存在栈里.2.复杂 ...

  2. 一些js面试高频知识点的总结

    第一部分:Object Prototypes (对象原型) (1)定义一个方法,要求传入一个string类型的参数,然后将string的每个字符间加个空格返回,例如: spacify('hello w ...

  3. MySQL:比较两个数据表不同部分

    简单比较 1.SELECT * FROM t2 WHERE id NOT IN (SELECT id FROM t1); 2.SELECT * FROM t2 WHERE NOT EXISTS(SEL ...

  4. description The request sent by the client was syntactically incorrect.

    shi用url传递参数,其他页面都ojbk的 唯独有一个请求 不应该啊 这明显的已经配置好了啊 因为别的请求我也是这样配置的啊,运行是没问题的啊 运行好好的啊 一时间,感觉无从下手了 经过十几分钟各种 ...

  5. CSS利用filter/opacity实现背景透明

    先看看众所周知的解决方案 如果我们想要一个半透明背景,有两种实现方式: 1.利用CSS和opacity属性 .opacity { filter:alpha(opacity=);/*IE浏览器*/ op ...

  6. Spring事务_注解_特性

    Spring 是一个 IOC 和 AOP 容器框架. ## 控制反转(IOC) ## 传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new 或者 getInstance 等直接或者间 ...

  7. NOIP模拟 6.26

    T1 子矩阵 题目描述 小A有一个N×M的矩阵,矩阵中1~N*M这(N*M)个整数均出现过一次.现在小A在这个矩阵内选择一个子矩阵,其权值等于这个子矩阵中的所有数的最小值.小A想知道,如果他选择的子矩 ...

  8. mybatis的第一个程序

    程序结构图: 表结构: 创表sql: CREATE TABLE `users` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `username` varch ...

  9. No.6 Verilog 其他论题

    (1)任务  **任务类似于一段程序,可以提供一种能力,使设计者可以从设计描述的不同位置执行共同的代码段.任务可以包含时序控制, 可以调用其它任务和函数.  任务的定义格式: task[automat ...

  10. sqlserver 大数据量的insert、delete操作优化

    http://blog.csdn.net/lanyuzhen/article/details/7547476 --大批量导出orders表:insert DBCC DROPCLEANBUFFERS   ...