hdu 1025 二分法求LIS

利用二分查找的方式实现求解LIS(最长上升子序列)问题 我们在之前讲过复杂度为O(n^2)的LIS模型,在较大输入规模会超时,所以利用复杂度较小为O(nlogn)的二分查找的LIS模型 来解决LIS普遍性问题。函数返回的是目标值第一次出现的索引,如果目标值在数组中不存在,则返回一个使得目标值可以插入到数组中而不破坏有序性的位置。函数返回的是不小于目标值的第一个元素的迭代器,如果所有元素都小于目标值,则返回容器的。这两种方法之间的区别在于它们在查找目标值时返回的具体位置。函数返回的是一个迭代器,而自定义的。函数返回的是一个索引(位置)。 阅读详情

      题目给出两个序列,两个序列间有边相连,我们要选出不交叉的边,使得所选的边最多

     我们发现,如果我们对其中一个序列从小到大排序的话,这个问题就变成了求另一个序列的最长上升子序列的问题。

     由于这个题目的数据比较大,一般的求最长上升子序列的方法是n方的,显然不能满足题目的要求,我们建立一个数组g,g[i]表示长度为i的上升子序列最后一个数的最小值,那么显然g数组是严格单调的,确切的说是严格单调上升的,那么,我们想到利用二分的方法对LIS进行优化,对于一个数x,找到数组g中第一个大于x的数的位置,如果找不到,就将序列的长度增加1,g[len]=x,否则,由于x小于目前找到的这个位置上的数,我们用x更新g数组,即g[第一个大于x的位置]=x

    这样我们就得到了一个新的求LIS的算法,并且这个算法的时间复杂度是O(nlogn),这样的话就可以很好的解决这个问题了。

    另外,这个题还有一个陷阱:就是当找到的序列长度如果大于1输出的是roads否则是road,我就因为没有注意到这个wa了好几次TAT

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

struct node
{
    int x,y;
}a[500005];

int n,k,q=0;
int g[500005];

void lis(int x)
{
    int l=0,r=k-1;
    while (l<r)
    {
        int mid=(l+r)>>1;
        if (g[mid]>x) r=mid;
        else l=mid+1;
    }
    if ((l==k-1)&&(g[k-1]<x)) {g[k]=x; k++; return;}
    if (g[l]>x) g[l]=x;
}

bool cmp(node a,node b)
{
    return a.x<b.x;
}

int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        q++;
        for (int i=0;i<n;i++)
        {
            int j,k;
            scanf("%d%d",&j,&k);
            a[i].x=j; a[i].y=k;
        }
        sort(a,a+n,cmp);
        k=1;
        memset(g,0,sizeof(g));
        g[0]=a[0].y;
        for (int i=1;i<n;i++) lis(a[i].y);
        if (k>1) printf("Case %d:\nMy king, at most %d roads can be built.\n\n",q,k);
        else printf("Case %d:\nMy king, at most %d road can be built.\n\n",q,k);
    }
    return 0;
}


求LIS的两种方法:DP 与 二分法 ~~ LIS(Longest Increasing Subsequence):最长上升子序列 这里分两种情况来看: 子序列严格递增(即子序列中不能存在相等) 子序列非降(即子序列中可以存在相等) 对于序列:a[1] , a[2] , a[3] , … , a[N] 一、动态规划(DP)   时间复杂度:O(N2) 子序列严格递增:dp[i] = max{1 , dp[j]+1}   ( j&amp;amp;amp;amp;lt... 阅读详情

相关推荐

黑金ZYNQ7010开发板开箱实测:从接线到串口通信的保姆级指南

本文提供黑金ZYNQ7010开发板从开箱到串口通信的完整实操指南。详细介绍了硬件连接、驱动安装、启动模式设置及串口终端配置等关键步骤,并针对常见问题提供排查思路,帮助FPGA开发者快速上手ZYNQ平台,建立稳定的调试通道。

weixin_29266749的博客 466

LIS(最长上升子序列)问题的三种求解方法以及一些例题

摘要本篇博客介绍了求LIS的三种方法,分别是O(n^2)的DP,O(nlogn)的二分+贪心法,以及O(nlogn)的树状数组优化的DP,后面给出了4道LIS的例题。LIS的定义一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序列(ai1, ai2, …, aiK),这里1 <= i1 <

George__Yu的博客 2万+

用户视角下的vfsglobal预约困境:从注册到登录的全流程避坑指南

本文详细解析了vfsglobal签证预约系统从注册到登录的全流程操作,帮助用户避开常见技术陷阱。针对IP限制、DNS解析、浏览器缓存等登录障碍提供实用解决方案,并揭示账号管理的隐藏规则与支付环节的延时处理技巧,助力用户高效完成签证预约。

ol78901234的博客 871

动态规划(二分法改进):LIS问题以及应用题 (子序列型)

LIS问题解决思路,着手dp数组记录下长度为b的单调递增子序列最小结束元素。 Example: array = [2,1,4,3,8,7,5,6,9] 对每个元素array[i]进行单独判断,考虑array[i]可构成最长为多长的局部LIS。 局部的搜索采用二分,以dp数组为域,以array[i]为判定值,找到一个dp中的位置 j 满足: ( dp[j]<array[i] and ...

qq_42418728的博客 777

HDR标准核心参数全解析:从PQ/HLG到元数据,一篇搞懂技术选型

本文全面解析HDR标准的核心参数,包括PQ/HLG传输函数和元数据机制,帮助读者理解技术选型的关键因素。通过对比主流HDR标准的技术细节,提供从内容创作到硬件适配的实用指南,助力实现更真实的视觉体验。

weixin_31766003的博客 300

实测对比:DINOv2、CLIP、ResNet在图像相似度任务上谁更强?(含Python代码与避坑指南)

本文通过实测对比DINOv2、CLIP和ResNet在图像相似度任务中的表现,提供Python代码实现与避坑指南。实验结果显示,DINOv2在精度上表现最佳,CLIP在多模态场景中优势明显,而ResNet则在计算效率上更优。文章还针对不同业务场景给出了具体选型建议,帮助开发者在图像搜索和版权检测等项目中做出更明智的技术决策。

weixin_30588381的博客 286

HDU1025-二分求LIS。

1.题目链接。说了很多,但是一句话可以概括。在平行线的之间有一些线段,取一组线段使得任意两条不相交,求最多有多少条这样的线段。 2.分析:为什么就是转化成了LIS了呢?其实这个很简单,我们只需要考虑一条边,从1到n,然后把另一条边上的数字映射上来,并且是一一对应的,所以就是个数组了。a[i]=j;代表i和j之间有一条线段,做完这个映射之后,我们可以观察到,如果在poor cities中,i&lt...

YG爱木木 454

Pointnet++环境配置+复现

深度学习点云经典网络Pointnet++

weixin_58663121的博客 8075

LIS

HDU 1025 最长上升子序列:就是求一个数组中,从小到大最多个那个子序列 比如 3 5 1 6 8 4 9 10中最长的就是3 5 6 8 9 10 这个题有时间要求,如果两个for循环的话会超时,所以可以用贪心加二分法 二分法注意求下一个遍历的元素可以替换掉已有子序列里的哪个。 有以下序列A[ ] = 3 1 2 6 4 5 10 7,求LIS长度。 我们定义一个B[ i ]来储存可能的...

太菜了 200

如何计算 R 中的基尼系数(附示例)

以意大利统计学家Corrado Gini命名,基尼系数是衡量人口收入分配的一种方法。基尼系数的值在 0 到 1 之间,值越高代表收入不平等越大,其中:0代表完全的收入平等(每个人的收入都一样) 1代表完全的收入不平等(一个人拥有所有收入) 您可以在此处找到按国家/地区列出的基尼系数列表。以下示例显示了使用DescTools包中的Gini()函数计算 R 中的基尼系数的两种方法。示例 1:使用个人收入计算基尼系数假设我们有以下 10 个人的年收入列表:收入:5 万美元、5 万美元、7 万美元、7 万美元、7

Mrrunsen的博客 2991

微店构造订单页面,自动化抢票

之前的文章写过微店抢票如何构造订单页面分析,这篇文章在之前的基础上,进行抢票。

猫敷雪 7202

HDU1025_Constructing Roads In JGShining's Kingdom【LIS】【二分法】

题目大意:路两旁各有N个城市,一旁N个富城市,一旁N个穷城市,每个穷 城市缺少一种资源(各不相同),每个富城市拥有一种资源(各不相同),穷城市 p需要从富城市r得到这种资源,就得修路。为了不造成交通堵塞,修的路不能 有交叉,问最多能修几条路,也就是有几个城市得到资源。 思路:就是给你两边各N个点,在这两边连线,每个点只能连一次,问最多有 多少线不交叉。把一边的点按升序排列,那么题目就转换为求另一边的最大上 升子序列了,而这道题数据规模为500000,O(N^2)算法肯定超时,只能用 栈+二分法的O(Nlog

程序员充电站(itcharge) 1442

低功耗设计:如何计算power switch的数量?

power switch加多了漏电高,加少了ir drop会有问题,具体加多少合适要如何计算呢?这里可以给一个参考方式。 第一步,先选switch cell的类型 通常选用HVT类型的switch cell,优点是漏电更低,缺点也很明显,电阻大,压降也大,switch cell的大小选择,可以选择(开启电阻x面积)最小的switch cell,即单位面积提供最小并联电阻的cell类型。 第二步,计算数量 选好类型,确定了开启电阻,可以按照如下公式计算数量: Ron/Xnum • W/V = V•P

m0_61544122的博客 3577

HDU 1025 (DP+二分法)

#include #include #include using namespace std; int d[500010]; int result[500010]; int roadNum = 0; int dp(){ result[1] = d[1]; int index = 1; for (int k=2;k<=roadNum;k++){ int p =

xiao597896577的专栏 445

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

HDU 1025 Constructing Roads In JGShining's Kingdom

思路:         仔细考虑就是求最长公共子序列问题          最长公共子序列的算法:         (1)通过dp求,好理解O(n*n);(此题不能用DP会超时)         (2)通过二分法求O(n*lgn);            过程如下: 假设存在一个序列d[1..9] = 2 1 5 3 6 4 8 9 7,可以看出来它的LIS长度为5。 下面一步一步试

Job_yi的专栏 740

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

HDU-1025,最长上升子序列(nlogn)算法+详解

题目连接 分析: 此题就是一个最长上升子序列的一个变形题,没什么难度。关于LIS问题,有两种算法,一种是dp,时间复杂度为n^2,另一个是二分+Dp,之所以能用二分查找,关键在于它用辅助数组保存了具有递增的数据,正好适宜二分查找。而查找的整个序列D中,有错落的递增式,也就必定存在最长的一个,它们的元素就构成了一个递增有序的集合M,第一个必定是在M中最小,而且第一个最小的元素,一定是在D中靠前的

ZXLS-ZMR的专栏 1221

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

hdu1025 dp(最长上升子序列LIS)

题意:有一些穷国和一些富国分别排在两条直线上,每个穷国和一个富国之间可以建道路,但是路不能交叉,给出每个穷国和富国的联系,求最多能建多少条路 我一开始在想有点像二分图匹配orz,很快就发现,当我把穷国按顺序排了之后,富国写在它旁边,能够连接的富国就成了一个上升子序列,那么问题来了!上升子序列最长有多长? 想到了这个之后,代码就码起来吧,最开始我的做法是最土的那种,用 dp[i] 表示以 i 结...

weixin_34014277的博客 125

hdu1025 最长上升子序列 O(nlogn)优化版

这题坑点挺多。 首先,输入很大,虽然看懂了是最长上升子序列,但第一次用朴素查找,妥妥的超时了。。 学习一下二分查找LIS,可以优化到O(nlogn)。 还有就是英文输出时,一定要注意复数复数!!之前有道题也是用到各种数序的英文输出。不注意的话就会WA。 二分查找LIS,其实就是拿一个数组f[],下标表示长度,存放该长度序列的末尾数。该数组存放的末尾数也一定是递增的。 #inc

ayu的博客 375

hdu 1025 Constructing Roads In JGShining's Kingdom

很容易知道,这个题就是求最大上升子序列。把图画一画就知道了。 如果用经典的DP双重for循环肯定超时。于是从网上搜解题报告才知道是用二分。 于是把 LIS 的二分方法写了一遍。 对二分的思想还是体会不够深啊。 #include int num[500010],ans[500010]; int main() { int i,n,p,r,cas=1; int le

水人之路 662

hdu1025整合此题网络解题思路

Hdu1025

linxingqianglai的专栏 610

暑期dp46道(16)hdoj 1025 Constructing Roads In JGShining's Kingdom最长上升子序列(二分)

题目链接:hdu 1025 题意:这题很容易想到最长上升子序列的模型,但是高高兴兴写出来也会TLE。。懵逼   不过也是,看这个复杂度500000,o(n^2)铁定挂啊,所以就需要优化,二分法就可以。 话不多说,上模板: void Do() { dp[1]=data[1]; int r,l,len=1; for(int i=2

退役ACMer 496

HDU1025 Constructing Roads In JGShining's Kingdom(最长递增子序列)

题目大意:求一列数的最长子序列;题目链接 题目解析:DP+二分 假设存在一个序列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一

陌上花开 825

HDU1025 动态规划 dp+二分搜索

收获: 1:dp+二分  NlogN的复杂度 2:二分法的使用 3:dp[i]记录的是上升最大序列为i的最小数 4:注意格式 最后是要输出两个空行 #include &lt;iostream&gt; #include &lt;map&gt; #include &lt;cstdio&gt; #include &lt;cstring&gt; using namespace std; c...

qq_41755258的博客 163

HDU_1025 Constructing Roads In JGShining's Kingdom

       借杭电这道题总结一下最长上升子序列(LIS)问题,最长上升子序列有o(n^2)和o(nlogn)两种算法(Matrix67那还有一种o(nm)的算法,不过没看懂)。   o(n^2)算法不用多说,就是依次遍历整个序列,每一次求出从第一个数到当前这个数的最长上升子序列,直至遍历到最后一个数字为止,然后再取dp数组里最大的那个即为整个序列的最长上升子序列。我们用dp[i]来存放序列1-...

weixin_34192816的博客 86

HDU - 1025 Constructing Roads In JGShining's Kingdom (nlogn 最长上升子序列

题意: 求最长上升子序列,但这个要用二分法: 博客参考:https://blog.youkuaiyun.com/idealistic/article/details/52181408 #include&lt;iostream&gt; using namespace std; long d[500001],a[500001]; //d[i]用来存最长不降子序列 最后一个元素 long find(...

lanshan1111的博客 189
上一篇: hdu 1269 迷宫城堡
下一篇: STL中栈、队列和优先队列的使用
EzCUfST
博客等级 码龄12年 1粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值