HDU 1025 (LIS+二分) Constructing Roads In JGShining's Kingdom
这是最大上升子序列的变形,可并没有LIS那么简单。
需要用到二分查找来优化。
看了别人的代码,给人一种虽不明但觉厉的赶脚
直接复制粘贴了,嘿嘿
原文链接:
http://blog.csdn.net/ice_crazy/article/details/7536332
假设存在一个序列d[1..9] = 2 1 5 3 6 4 8 9 7,可以看出来它的LIS长度为5。
下面一步一步试着找出它。
我们定义一个序列B,然后令 i = 1 to 9 逐个考察这个序列。
此外,我们用一个变量Len来记录现在最长算到多少了
首先,把d[1]有序地放到B里,令B[1] = 2,就是说当只有1一个数字2的时候,长度为1的LIS的最小末尾是2。这时Len=1
然后,把d[2]有序地放到B里,令B[1] = 1,就是说长度为1的LIS的最小末尾是1,d[1]=2已经没用了,很容易理解吧。这时Len=1
接着,d[3] = 5,d[3]>B[1],所以令B[1+1]=B[2]=d[3]=5,就是说长度为2的LIS的最小末尾是5,很容易理解吧。这时候B[1..2] = 1, 5,Len=2
再来,d[4] = 3,它正好加在1,5之间,放在1的位置显然不合适,因为1小于3,长度为1的LIS最小末尾应该是1,这样很容易推知,长度为2的LIS最小末尾是3,于是可以把5淘汰掉,这时候B[1..2] = 1, 3,Len = 2
继续,d[5] = 6,它在3后面,因为B[2] = 3, 而6在3后面,于是很容易可以推知B[3] = 6, 这时B[1..3] = 1, 3, 6,还是很容易理解吧? Len = 3 了噢。
第6个, d[6] = 4,你看它在3和6之间,于是我们就可以把6替换掉,得到B[3] = 4。B[1..3] = 1, 3, 4, Len继续等于3
第7个, d[7] = 8,它很大,比4大,嗯。于是B[4] = 8。Len变成4了
第8个, d[8] = 9,得到B[5] = 9,嗯。Len继续增大,到5了。
最后一个, d[9] = 7,它在B[3] = 4和B[4] = 8之间,所以我们知道,最新的B[4] =7,B[1..5] = 1, 3, 4, 7, 9,Len = 5。
于是我们知道了LIS的长度为5。
!!!!! 注意。这个1,3,4,7,9不是LIS,它只是存储的对应长度LIS的最小末尾。有了这个末尾,我们就可以一个一个地插入数据。虽然最后一个d[9] = 7更新进去对于这组数据没有什么意义,但是如果后面再出现两个数字 8 和 9,那么就可以把8更新到d[5], 9更新到d[6],得出LIS的长度为6。
然后应该发现一件事情了:在B中插入数据是有序的,而且是进行替换而不需要挪动——也就是说,我们可以使用二分查找,将每一个数字的插入时间优化到O(logN)~~~~~于是算法的时间复杂度就降低到了O(NlogN)~
看完以后,感觉明白了一些
上面的B[i]存放的是长度为i的LIS的最小末尾
最后直接输出len的值就好了
可是为什么这样算捏??
还是暂时先记住吧
自己写了个二分还给“哇”了,淡淡的忧桑
把别人的二分查找拿过来,学习了!
//#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; const int maxn = + ;
int a[maxn];
int dp[maxn]; int main(void)
{
#ifdef LOCAL
freopen("1025in.txt", "r", stdin);
#endif int n, kase = ;
while(scanf("%d", &n) == )
{
int i;
for(i = ; i <= n; ++i)
{
int c, m;
scanf("%d%d", &c, &m);
a[c] = m;
}
dp[] = a[]; int len = ;
for(i = ; i <= n; ++i)
{
int left = ;
int right = len;
while(left <= right)
{
int mid = (left + right) / ;
if(dp[mid] < a[i])
left = mid + ;
else
right = mid - ;
}
dp[left] = a[i];
if(left > len)
++len;
} printf("Case %d:\n", ++kase);
if(len == )
printf("My king, at most 1 road can be built.\n\n");
else
printf("My king, at most %d roads can be built.\n\n", len);
}
return ;
}
代码君
HDU 1025 (LIS+二分) Constructing Roads In JGShining's Kingdom的更多相关文章
- HDU 1025:Constructing Roads In JGShining's Kingdom(LIS+二分优化)
http://acm.hdu.edu.cn/showproblem.php?pid=1025 Constructing Roads In JGShining's Kingdom Problem Des ...
- HDU 1025 Constructing Roads In JGShining's Kingdom(二维LIS)
Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65 ...
- hdu 1025:Constructing Roads In JGShining's Kingdom(DP + 二分优化)
Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65 ...
- Constructing Roads In JGShining's Kingdom(HDU 1025 LIS nlogn方法)
Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65 ...
- HDOJ(HDU).1025 Constructing Roads In JGShining's Kingdom (DP)
HDOJ(HDU).1025 Constructing Roads In JGShining's Kingdom (DP) 点我挑战题目 题目分析 题目大意就是给出两两配对的poor city和ric ...
- HDU 1025 Constructing Roads In JGShining's Kingdom[动态规划/nlogn求最长非递减子序列]
Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65 ...
- hdu--(1025)Constructing Roads In JGShining's Kingdom(dp/LIS+二分)
Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65 ...
- [ACM] hdu 1025 Constructing Roads In JGShining's Kingdom (最长递增子序列,lower_bound使用)
Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65 ...
- HDU 1025 LIS二分优化
题目链接: acm.hdu.edu.cn/showproblem.php?pid=1025 Constructing Roads In JGShining's Kingdom Time Limit: ...
随机推荐
- Treap模板
平衡树总是有用的,set由于过度封装没有办法实现找比x小的元素有多少个,这就显得很不方便了,所以封装了个Treap,万一以后用的着呢- -01 #pragma warning(disable:4996 ...
- LA 4727
Integers 1, 2, 3,..., n are placed on a circle in the increasing order as in the following figure. W ...
- POJ 3276
Face The Right Way Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 2193 Accepted: 103 ...
- POJ 1811 Prime Test (Pollard rho 大整数分解)
题意:给出一个N,若N为素数,输出Prime.若为合数,输出最小的素因子.思路:Pollard rho大整数分解,模板题 #include <iostream> #include < ...
- Android中将布局文件/View添加至窗口过程分析 ---- 从setContentView()谈起
本文主要内容是讲解一个视图View或者一个ViewGroup对象是如何添加至应用程序窗口中的.下文中提到的窗口可泛指我们能看到的界面,包括一个Activity呈现的界面(我们可以将之理解为应用程序窗口 ...
- Android——横屏和竖屏的切换,以及明文密码的显示
查看API文档: android.content.pm.ActivityInfo 在手机的使用中,我们要根据不同的需求来改变屏幕的显示方向,一般在浏览信息时是竖屏,在玩游戏的时候就要切换到横屏. ...
- 饶有兴致的用javascript做了个贪食蛇游戏
09年写的东西.一直藏在自己的记事本里头,现在开始整理写博客,所以直接搬过来 先上效果图 再添代码: <HTML> <HEAD> <TITLE>贪吃蛇 Snake ...
- 记一段使用node对mysql数据库做处理
所用到的存储过程如下: temp_get_userCount: BEGIN #Routine body goes here... SELECT COUNT(id) as num FROM tbl_us ...
- mfc和win32区别
Win32通常是指sdk编程方法,app没有被封装,开发人员需要自己搭程序框架:mfC则是以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量 (整理 ...
- VS 解决方案目录结构设置
涉及到的配置: 项目编译时使用的中间目录: 项目链接的输出目录: 项目编译结束后,拷贝生成的 dll 和 lib 到指定目录: 项目编译结束后,拷贝需要的 dll 到输出目录: 设置项目的工作目录: ...