这个博客说的已经很好了。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. Luogu P2292 [HNOI2004]L语言(Trie+dp)

    P2292 [HNOI2004]L语言 题面 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章 \(T\) 是由若干小写字母构成. ...

  2. 【html、CSS、javascript-10】jquery-操作元素(属性CSS和文档处理)

    一.获得内容及属性 三个简单实用的用于 DOM 操作的 jQuery 方法: text() - 设置或返回所选元素的文本内容 html() - 设置或返回所选元素的内容(包括 HTML 标记) val ...

  3. MAC中怎么安装python

    转自:https://blog.csdn.net/hou_manager/article/details/79555809 一.Python 介绍 Python介绍 Python3在2008年12月3 ...

  4. TZ_16ES6学习总结

    1.块级作用域的引入 在ES6之前,js只有全局作用域和函数作用域,ES6中let关键字为其引入了块级作用域. { var a = 5; let b = 6; } console.log(a); // ...

  5. TZ_13_Hystix的服务降级_线程隔离

    1.微服务中,服务之间的调用关系复杂. 一个请求有可能需要多个微服务接口才能实现.如果一次请求出现问题就会直接堵塞,占用一次tomcat链接.如果访问这个出现问题的请求就会造成tomcat请求链接都被 ...

  6. vue项目 安装和配置sass & main.js引入scss文件报错

    通过npm 安装 cnpm install --save-dev sass-loader cnpm install --save-dev node-sass 在build文件夹下的webpack.ba ...

  7. I Hate It HDU - 1754 (线段树)

    注意点:scanf中使用%c时,会读取空格和回车,所以在%c之前要有一个空格 ( 或者直接使用%s也行,%s会忽略空格和回车 ).具体见下面的代码: #include<iostream> ...

  8. 为什么打不开IDEA或webStorm官方网页?

    为什么打不开IDEA或webStorm官方网页? 一.问题描述 idea和webStorm的官网:https://www.jetbrains.com/ 有时候打开idea的官网会出现无法访问的情况,页 ...

  9. Centos无法连接无线网络解决办法

    系统->管理->服务器设置->服务,将NetworkManager选项勾选,点击重启服务.然后就可以看到右上角已经有了网络连接.

  10. IP地址与,域名,DNS服务器,端口号的联系与概念

    一,什么是IP地址? 每一个联入到Internet的计算机都需要一个世界上独一无二的IP地址,相当于人们的身份证号码! IP地址有A类,B类,C类,D类和E类之分,目前D类和E类都暂时作为保留地址! ...