求最长上升子序列长度:

单纯的dp时间复杂度是O(n*n)的

dp[i] = max(dp[j]+1); (0=<j<=i-1 && a[i]>a[j])

用二分可以减少查找的时间:时间复杂度:O(n*log(n))

模板:

#define maxn 100010
int a[maxn], b[maxn]; // 二分在b[] 数组里找第一个比num 大的数的位置。
int search_(int num, int low, int high) {
int mid;
while(low <= high) {
mid = (low+high)/2;
if (num >= b[mid]) low = mid + 1;
else high = mid - 1;
}
return low;
} int LIS(int n) {
int i, len, pos;
b[1] = a[1];
len = 1;
for (i=2; i<=n; ++i) {
if (a[i] > b[len]) {// 如果a[i]比b[]中最大的数还大直接插入到最后。 //如果是非递减序列,改为 >= 即可。
len = len + 1;
b[len] = a[i];
}
else {
pos = search_(a[i], 1, len);
b[pos] = a[i];
}
}
return len;
}

Eg:题目链接:The All-purpose Zero

题意:给一个序列,序列里的0可以代替任何数,问这个序列里最长递增子序列的长度。0也可以代替负数。(如果不可以的话...)

思路:因为0可以代替任何数,所以ans一定是优先选择0的,然后把每个数减掉它前面的0的个数。为什么减0呢... 比如:1 2 0 3 优先选0,3-1=2,... ,这样就变成了1 2 2 ...求最长上升子序列的长度+0的个数。

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std; #define maxn 100010
int a[maxn], b[maxn]; // 二分在b[] 数组里找第一个比num 大的数的位置。
int search_(int num, int low, int high) {
int mid;
while(low <= high) {
mid = (low+high)/2;
if (num >= b[mid]) low = mid + 1;
else high = mid - 1;
}
return low;
} int LIS(int n) {
int i, len, pos;
b[1] = a[1];
len = 1;
for (i=2; i<=n; ++i) {
if (a[i] > b[len]) {// 如果a[i]比b[]中最大的数还大直接插入到最后。 //如果是非递减序列,改为 >= 即可。
len = len + 1;
b[len] = a[i];
}
else {
pos = search_(a[i], 1, len);
b[pos] = a[i];
}
}
return len;
} int main() {
//freopen("in.cpp", "r", stdin);
int t;
scanf("%d", &t);
int cas = 0;
while(t--) {
int n;
scanf("%d", &n);
int zeroNum = 0, cnt = 0;
for (int i=0; i<n; ++i) {
int temp;
scanf("%d", &temp);
if (temp == 0) zeroNum++;
else {
temp -= zeroNum;
a[++cnt] = temp;
}
}
int ans = LIS(cnt) + zeroNum;
if (cnt == 0) ans -= 1;
printf("Case #%d: %d\n", ++cas, ans);
}
return 0;
}

HDU 5773 The All-purpose Zero 求LIS的更多相关文章

  1. hdu 1025LIS思路同1257 二分求LIS

    题目: Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit ...

  2. HDU 5773 The All-purpose Zero(O(nlgn)求LIS)

    http://acm.hdu.edu.cn/showproblem.php?pid=5773 题意: 求LIS,其中的0可以看做任何数. 思路: 因为0可以看做任何数,所以我们可以先不管0,先求一遍L ...

  3. HDU 5773:The All-purpose Zero(贪心+LIS)

    http://acm.hdu.edu.cn/showproblem.php?pid=5773 The All-purpose Zero Problem Description   ?? gets an ...

  4. HDU 5773 The All-purpose Zero 脑洞LIS

    给定一个序列,里面的0是可以任变的.问变化后最长的LIS的长度 首先,0全部选上是不亏的.这个不知道怎么说,YY一下吧. 最关键的就是解决2 0 0 3 这种问题了. 注意到这个序列的LIS应该是3 ...

  5. hdu 5773 The All-purpose Zero 最长上升子序列+树状数组

    题目链接:hdu 5773 The All-purpose Zero 官方题解:0可以转化成任意整数,包括负数,显然求LIS时尽量把0都放进去必定是正确的. 因此我们可以把0拿出来,对剩下的做O(nl ...

  6. hdu 1950 最长上升子序列(lis) nlogn算法【dp】

    这个博客说的已经很好了.http://blog.csdn.net/shuangde800/article/details/7474903 简单记录一下自己学的: 问题就是求一个数列最长上升子序列的长度 ...

  7. Codeforces 486E LIS of Sequence --树状数组求LIS

    题意: 一个序列可能有多个最长子序列,现在问每个元素是以下三个种类的哪一类: 1.不属于任何一个最长子序列 2.属于其中某些但不是全部最长子序列 3.属于全部最长子序列 解法: 我们先求出dp1[i] ...

  8. HDU 5773 The All-purpose Zero

    这题想了1个多小时想不出来...方法真是精妙... 官方题解:0可以转化成任意整数,包括负数,显然求LIS时尽量把0都放进去必定是正确的.因此我们可以把0拿出来,对剩下 的做O(nlogn)的LIS, ...

  9. hdu5256 二分求LIS+思维

    解题的思路很巧,为了让每个数之间都留出对应的上升空间,使a[i]=a[i]-i,然后再求LIS 另外二分求LIS是比较快的 #include<bits/stdc++.h> #define ...

  10. poj1631——树状数组求LIS

    题目:http://poj.org/problem?id=1631 求LIS即可,我使用了树状数组. 代码如下: #include<iostream> #include<cstdio ...

随机推荐

  1. MVC加载下拉列表

    public ActionResult GetList() { string strSql = "select staff_id,nick_name from tbl_ac_info whe ...

  2. shiro连接数据库

    建一个jdbcRealm.ini [main] jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm dataSource=com.mchange.v2.c3 ...

  3. Python学习(8)字符串

    目录 Python 字符串 Python 访问字符串中的值 Python 字符串更新 Python 转义字符 Python 字符串运算符 Python 字符串格式化 Python 三引号 Unicod ...

  4. 树状数组求逆序对:POJ 2299、3067

    前几天开始看树状数组了,然后开始找题来刷. 首先是 POJ 2299 Ultra-QuickSort: http://poj.org/problem?id=2299 这题是指给你一个无序序列,只能交换 ...

  5. bzoj3529(莫比乌斯反演+离线+树状数组)

    在你以为理解mobus的时候,苦苦想通过化简公式来降低复杂度时,这题又打了我一巴掌. 看来我并没有理解到acmicpc比赛的宗旨啊. 这么多次查询可以考虑离线操作,使用树状数组单点更新. /***** ...

  6. Logger日志级别说明及设置方法、说明 (zhuan)

    http://blog.csdn.net/rogger_chen/article/details/50587920 ****************************************** ...

  7. 百度地图-marker拖拉,右键菜单

    marker拖拉,修改经纬度. //创建Map实例 var map = new BMap.Map("allmap"); var point=new BMap.Point(104.0 ...

  8. Hbase之取出行数据指定部分(类似MySQL的Limit)

    import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.CellScanner; import org. ...

  9. modernizer的意义

    modernizer是一个js文件,会检查当前的浏览器支持什么特性,就在Html标签上添加什么类,然后如果不支持添加no-xxx类,这样,就可以针对两种情况写两种css. http://blog.ch ...

  10. OpenCV3编程入门笔记(4)腐蚀、膨胀、开闭运算、漫水填充、金字塔、阈值化、霍夫变换

    腐蚀erode.膨胀dilate 腐蚀和膨胀是针对图像中的白色部分(高亮部分)而言的,不是黑色的.除了输入输出图像外,还需传入模板算子element,opencv中有三种可以选择:矩形MORPH_RE ...