`
wunke
  • 浏览: 10742 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

最长不降子序nlogn 原理

阅读更多

问题描述:给出一个序列,找出其最长不降子充

例如:4 1 3 5 6 2 7结果为:1 3 5 6

题解:

数组ID[n] = {4 1 3 5 6 2 7}.

数组F[n],设j指向ID,i指向F,F[i]表示在长度为j的序列中,最长不降子序长度为i的子序列的最后一个元素的最小值。所以递推公式为:

0<=i<=len(len:为已求出的最长不降子序的长度)

如果ID[j] <= F[i] (即:长度为i的不降子序的最后一个元素有更小的值ID[j],

则更新F[i])则F[i] = ID[j]

如果i == len 并且 ID[j] > F[i ] (即:ID[j] 可以叠加到已求出的最长子序列上,成为len = len+1长度的不降子序上)。则F[i +1] = ID[j]

则最后我们的答案就是len

这样很明显我们的程序有两个for循环,分别是i,j(0<=j<=n,0<=i<=len)

这样一个个查找的时间为n*n

由于F[i]表示在长度为j的序列中,最长不降子序长度为i的子序列的最后一个元素的最小值,所以F为递增,可以用二分查找法找出将要刷新的F单元.

二分查找的时间为logn

所以总时间为n*logn

zju一道典型题

http://acm.zju.edu.cn/show_problem.php?pid=1986

输入数据量比较大,一定要用C的输入输出才可以AC

#include <iostream>
#include <stdio.h>
using namespace std;

int ID[40000],F[40000];
int main()
{
int Case,N;
//cin>>Case;
scanf("%d",&Case);
for(int i=0; i<Case; i++){
//cin>>N;
scanf("%d",&N);
int len = 0;
for(int j=0; j<N; j++){
//cin>>ID[j];
scanf("%d",&ID[j]);
//二分查找
int left=0,right=len-1;
int mid = 0;
while(left<=right){
mid = (left + right)/2;
if(ID[j] < F[mid])
right = mid-1;
else
left = mid+1;
}
if(left != len)
F[left] = ID[j];
else
F[len++]=ID[j];
}
//cout<<len<<endl;
printf("%d\n",len);
}
return 0;
}

分享到:
评论

相关推荐

    最长公共子序列算法总结

    在讨论最长公共子序列(Longest Common Subsequence,简称LCS)问题时,通常会提及两种主要的算法实现方式:一种时间复杂度为O(n^2),另一种则通过优化达到O(nlogn)的时间复杂度。下面我们将详细介绍这两种算法。 *...

    动态规划nlogn不上升序列

    此资源有助于帮助初学者较快掌握nlogn算法求动态规划中的经典例题---最长不上升序列(n&gt;100000)

    最长递增子序列C程序

    在给定的序列中,一个递增子序列是指一个不降序排列的子序列,即每个元素都大于或等于前一个元素。例如,对于序列`10, 9, 2, 5, 3, 7, 101, 4`,最长递增子序列有多个,其中一个是`2, 3, 7, 101`。 在C语言中实现...

    算法之NlogN排序算法(csdn)————程序.pdf

    本文旨在介绍NlogN时间复杂度的排序算法,深入分析其理论基础和实现原理,以便更好地理解和应用这些高效的排序方法。 一、递归行为和时间复杂度的估算 在分析排序算法的性能时,递归行为和时间复杂度的估算尤为...

    最长上升子序列优化代码

    动态规划的经典题目最长上升子序列,而且是经过二分优化的NlogN复杂度算法

    [转载]nlogn的最长子序列算法.rar_最长 排序_最长子序列

    总结起来,求解最长子序列问题的一种高效方法是结合排序和动态规划的思路,通过O(nlogn)的时间复杂度找到最长的非降序子序列。这种方法在实际应用中,如数据挖掘、算法竞赛等领域有着广泛的应用。

    C语言:基于c代码实现的最长上升子序列

    标题中提到的知识点是"C语言:基于c代码实现的最长上升子序列",描述部分则简单地提到了"最长上升子序列"。在给出的内容中,是一段C语言的代码,这段代码实现的是求解一个序列中最长上升子序列的长度。 首先,我们...

    python 实现 Dynamic Programming 动态规划 (Dynamic programming) 课程设计

    最长递增子序列 O(Nlogn) 最长的子阵列 矩阵链顺序 最大非邻和 最大乘积子阵列 最大子数组 最大和连续子序列 底部的最小距离 最小硬币兑换 最低成本路径 最小分区 最小大小子阵列总和 表示数字的最小...

    4NlogN求逆序数对1

    在合并过程中,若 `is1[i] [j]`,则将 `is1[i]` 放入 `is2[k++]`,不增加逆序对计数;反之,若 `is1[i] &gt; is1[j]`,则 `is1[j]` 提前,需要累加逆序对计数 `count += j - k`。最后,将 `is2` 写回原数组 `is1`。 在...

    数据结构排序之O(nlogn)堆排序

    **数据结构排序之O(nlogn)堆排序详解** 在计算机科学中,排序算法是处理大量数据的关键技术之一。O(nlogn)时间复杂度的排序算法,如堆排序,被视为高效算法,尤其适用于大数据集。堆排序是一种基于比较的排序方法,...

    DP问题不完全总结.pdf

    - 最长不下降子序列:状态(i)表示考虑前i个元素时的最长不下降子序列。通过单调栈或单调队列,可以将时间复杂度优化到O(nlogn)。 - LCS (最长公共子序列):状态(i, j)表示两个字符串第i和第j位置对应的最长公共子...

    NlogN经典排序算法的实现-希尔排序,快速排序,归并排序.zip

    **希尔排序、快速排序与归并排序:NlogN经典排序算法详解** 排序算法是计算机科学中的基础且重要的一部分,尤其是在处理大量数据时,高效排序能够显著提升程序性能。本资料包聚焦于三类时间复杂度为O(nlogn)的经典...

    最近邻点对O(nlogn)算法

    对于小规模的数据集,这种方法是可行的,但当n增大时,其效率会迅速下降。 **O(nlogn)算法**,则是一种更高效的方法。一种实现方式是使用kd树或者球树(如BBTree、Octree)。这些数据结构允许我们在近似O(logn)的...

    分治法求最大子段和的问题

    要求算法的时间复杂度不超过O(nlogn)。 最大子段和问题描述:给定由n个整数(可能为负整数)组成的序列a1, a2,…, an, 求该序列形如的子段和的最大值。当所有整数均为负整数时定义其最大子段和为0。依次定义,所求...

    DP、二分-LeetCode300. 最长上升子序列(Python)

    在LeetCode的第300题“最长上升子序列”中,目标是找出给定无序整数数组中的最长上升子序列(Longest Increasing Subsequence, LIS)的长度。这是一道经典的动态规划(Dynamic Programming, DP)和二分查找(Binary ...

    动态规划专题

    - 改进版动态规划:使用动态规划结合二分查找的方法,维护一个单调递增的序列,该序列的每个元素代表了长度为 `i` 的最长不下降子序列的最小结尾值。通过二分查找确定更新的位置,可以将时间复杂度降低到 `O(nlogn)`...

    分治法归并排序的C语言实现, 复杂度O(nlogn)

    归并排序是一种基于分治策略的高效排序算法,它的核心思想是将大问题分解成小问题,然后分别解决小问题,最后将小问题的答案合并,得到...这种算法对于理解数据结构和算法的底层工作原理,以及提升编程技巧非常有帮助。

    ACM资料字符串处理并差集

    通过对动态规划算法的改进,我们可以使用 O(nlogn)算法来解决最长上升子序列问题。这个算法的关键是使用二分查找来找到合适的元素,以便更快地计算最长上升子序列的长度。 五、最长公共子序列 最长公共子序列是指...

    数据与算法——实验报告——数列递增子序列

    这个过程中,二分查找的运用显著地提高了算法效率,将时间复杂度降至O(nlogn)。 ### 算法的正确性证明 算法的正确性通过数学归纳法得到证明。首先假定算法对长度为n的序列是正确的。当新的元素加入时,如果该元素...

Global site tag (gtag.js) - Google Analytics