洛谷 p1020 题解 求最长上升子序列的o(n*logn)算法

该博客详细介绍了如何解决洛谷P1020问题,即求最长下降子序列。博主指出传统方法可能会导致超时,提出了一种新的解法,通过反向枚举最长上升(下降)子序列的长度来避免超时。此外,博主还解释了为什么第二问实际上是在寻找最长递增子序列,并给出了逻辑推理。最后,博主分享了代码实现并表示这是自己首次接触这种方法,感到收获颇丰。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:

https://www.luogu.org/problemnew/solution/P1020

基本思路:

首先第一问是一个求最长下降子序列的问题,但是不能用传统的方法,因为会超时。还有个比较蛋疼的地方就是输入的时候,没有指定输入数据的个数,这个我也不会  ,看了题解才知道那么输入的。首先,基本的思路还是和传统的求最长上升(下降)子序列一样的,都是求以i为结尾的最长上升(下降)子序列,但是第2重循环可就大大不一样的,传统的是依次枚举以(1~~i-1)上的数为结尾的最长上升(下降)子序列,如果满足a[i]<a[j]或者a[i]>a[j],就执行dp[i]=max(dp[i],dp[j]+1);最终找出dp数组中最大的一个,就是结果。这是传统的解法。但是此题的第二重循环是依次枚举前i-1个数中所求得的递增(递减)子序列的长度(注意:是从最长的到最短的这个顺序开始枚举的  这很关键)

最终找到dp数组中的最大值,输出即可

代码如下:

#include<bits/stdc++.h>
using namespace std;
int visited[150000];//动归用的数组
int a[150000];
int t=0;//t表示当前所得到的最长上升子序列或最长下降子序列的长度
int z=0;//数据大小
int d1[150000],d2[150000];//d1[i],d2[i]表示子序列长度为i时上升(下降)子序列的最后一个元素在数组中的下标
int main()
{
    while(~scanf("%d",&a[++z]));//学到的新知识,对于不给定输入个数的数据的输入可以这样输入,也可以不等于EOF的那样输入
    z--;
    for(int i=1;i<=z;i++)//从这一行到25行是求的最长递减子序列(全新的方法,以前根本没用过,涨姿势了)
    {
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值