`

poj 2533

 
阅读更多

在做这道题目之前,首先让我们了解一下什么是LIS算法,LIS俗称最长不下降子序列,最长不下降子序列是一个非常常见的小问题,首先让我们了解一下什么是LIS

一 LIS描述如下:

L=<a1,a2,…,an>n个不同的实数的序列,L的递增子序列是这样一个子序列Lis=<aK1,ak2,…,akm>,其中k1<k2<…<kmaK1<ak2<…<akm。求最大的m值。

 

二 对于这类的题目一般有一下两种解法:

a、O(n^2)算法,思路如下:

(a[1]...a[n] 存的都是输入的数)
  1、对于a[n]来说,由于它是最后一个数,所以当从a[n]开始查找时,只存在长度为1的不下降子序列;
  2、若从a[n-1]开始查找,则存在下面的两种可能性:
  (1)若a[n-1] < a[n] 则存在长度为2的不下降子序列 a[n-1],a[n].
  (2)若a[n-1] > a[n] 则存在长度为1的不下降子序列 a[n-1]或者a[n]。
  3、一般若从a[t]开始,此时最长不下降子序列应该是按下列方法求出的:
  在a[t+1],a[t+2],...a[n]中,找出一个比a[t]大的且最长的不下降子序列,作为它的后继。
  4、为算法上的需要,定义一个数组:
  d:array [1..n,1..3] of integer;
  d[t,1]表示a[t]
  d[t,2]表示从i位置到达n的最长不下降子序列的长度
  d[t,3]表示从i位置开始最长不下降子序列的下一个位置

对于本题看代码如下:

// Memory Time 
// 228K   16MS 
// 
// O(n^2)算法
#include<iostream>
using namespace std;

int main(int i,int j)
{
	int n;
	while(cin>>n)
	{
		int* sq=new int[n];
		int* dp=new int[n];  //dp[i]表示以第i个位置为终点的最长不下降序列的长度
		
		for(i=0;i<n;i++)
			cin>>sq[i];
		
		int max_length=0;
		for(i=0;i<n;i++)
		{
			dp[i]=1;  //初始化dp[0]=1,其他最小值为1
			for(j=0;j<i;j++)
				if(sq[j]<sq[i] && dp[i]<dp[j]+1)
					dp[i]=dp[j]+1;
				
				if(max_length<dp[i])
					max_length=dp[i];
		}//双层for循环,算法复杂度为O(n*n)
		cout<<max_length<<endl;
		
		delete sq,dp;
	}
	return 0;
}

 

b、O(nlogn)算法

这个算法其实已经不是DP了,有点像贪心。至于复杂度降低其实是因为这个算法里面用到了二分搜索。本来有N个数要处理是O(n),每次计算要查找N次还是O(n),一共就是O(n^2);现在搜索换成了O(logn)的二分搜索,总的复杂度就变为O(nlogn)了。

这个算法的具体操作如下(by RyanWang):

开一个栈,每次取栈顶元素top和读到的元素temp做比较,如果temp > top 则将temp入栈;如果temp < top则二分查找栈中的比temp大的第1个数,并用temp替换它。 最长序列长度即为栈的大小top。

这也是很好理解的,对于x和y,如果x < y且Stack[y] < Stack[x],用Stack[x]替换Stack[y],此时的最长序列长度没有改变但序列Q的''潜力''增大了。

举例:原序列为1,5,8,3,6,7

栈为1,5,8,此时读到3,用3替换5,得到1,3,8; 再读6,用6替换8,得到1,3,6;再读7,得到最终栈为1,3,6,7。最长递增子序列为长度4。

 

具体看代码分析如下:

 

 

 

#include <iostream>
using namespace std;

const int SIZE=1001;

int main()
{
    int i, j, n, top, temp;
    int stack[SIZE];
    cin >> n;
	
    top = 0;
    /* 第一个元素可能为0 */
    stack[0] = -1;
    for (i = 0; i < n; i++)
    {
        cin >> temp;
        /* 比栈顶元素大数就入栈 */
        if (temp > stack[top])
        {
            stack[++top] = temp;
        }
        else
        {
            int low = 1, high = top;
            int mid;
            /* 二分检索栈中比temp大的第一个数 */
            while(low <= high)
            {
                mid = (low + high) / 2;
                if (temp > stack[mid])
                {
                    low = mid + 1;
                }
                else
                {
                    high = mid - 1;
                }
            }//在这个二分的过程中降低了算法的复杂度由于是二分查找的所以为o(logn),外边有一个for循环整体为O(nlogn)
            /* 用temp替换 */
            stack[low] = temp;
        }
    }
	
    /* 最长序列数就是栈的大小 */
    cout << top << endl;
	
    //system("pause");
    return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    POJ2533-Longest Ordered Subsequence

    标题“POJ2533-Longest Ordered Subsequence”是指北京大学在线判题系统POJ上的一道编程题目,其核心任务是寻找一个序列中最长的有序子序列。描述中的“解题报告+AC代码”表明这个压缩包包含了对这道问题的解答思路...

    北大POJ2533-Longest Ordered Subsequence【O(nlogn)】

    北大POJ2533-Longest Ordered Subsequence【O(nlogn)】

    北大POJ2533-Longest Ordered Subsequence【O(n^2)】

    北大POJ2533-Longest Ordered Subsequence【O(n^2)】

    POJ算法题目分类

    * 型如下表的简单 DP:型如下表的简单 DP 是指解决问题的简单 DP 算法,如 poj3267、poj1836、poj1260、poj2533。 * 计算几何学:计算几何学是指解决问题的计算几何学算法,如 poj2031、poj1039。 六、数学 数学...

    poj题目分类

    * 类型 DP:例如 poj3267、poj1836、poj1260、poj2533。 中级 1. 基本算法: * C++的标准模版库的应用:例如 poj3096、poj3007。 * 较为复杂的模拟题的训练:例如 poj3393、poj1472、poj3371、poj1027、poj2706...

    acm训练计划(poj的题)

    - (poj3267, poj1836, poj1260, poj2533):零一背包、完全背包等问题的解决方案。 3. **二维动态规划**: - (poj3176, poj1080, poj1159):多维状态转移方程的应用。 ### 五、组合数学 1. **排列组合基础**: ...

    经典 的POJ 分类

    - POJ 1260、POJ 2533:涉及多个变量的状态转移。 - POJ 3176、POJ 1080:复杂的状态空间定义与状态转移。 ### 数学问题 #### 组合数学 - **题目示例**: - POJ 3252、POJ 1850:组合数学原理的应用。 - POJ ...

    acm新手刷题攻略之poj

    ### ACM新手刷题攻略之POJ ... - 推荐题目:[poj3267](https://vjudge.net/problem/POJ-3267)、[poj1836](https://vjudge.net/problem/POJ-1836)、[poj1260](https://vjudge.net/problem/POJ-1260)、[poj2533]...

    ACM-POJ 算法训练指南

    1. **凸包**:构建点集的凸包(poj3267, poj1836, poj1260, poj2533)。 2. **线段交**:计算线段是否相交及交点位置(poj3176, poj1080, poj1159)。 ### 七、概率统计 1. **概率计算**:计算随机事件的概率(POJ...

    POJ 分类题目

    - poj2533 - poj3176 - poj1080 - poj1159 - **应用场景**:适用于路径规划、编辑距离计算等问题。 #### 六、数学 **1. 组合数学** - **定义**:研究离散对象的计数方法。 - **示例题目**: - poj1809 - poj...

    ACMer需要掌握的算法讲解 (2).docx

    * DP算法:POJ3267、POJ1836、POJ1260、POJ2533 二、图算法 * 度限制最小生成树和第K最短路:POJ1639、POJ3216、POJ2446 * 最优比率生成树:POJ2728 * 最小树形图:POJ3164 * 次小生成树 * 无向图、有向图的最小环...

    ACM常用算法及其相应的练习题.docx

    * 类似表的简单 DP:poj3267, poj1836, poj1260, poj2533 * 最长公共子序列:poj3176, poj1080, poj1159 * 最优二分检索树问题 六、数学 * 组合数学: + 加法原理和乘法原理 + 排列组合 + 递推关系 - poj3252...

    ACM常用算法及其相应的练习题 (2).docx

    (2) 简单DP:poj3267, poj1836, poj1260, poj2533 (3) 其他DP问题: 六、中级算法 本部分涵盖了中级算法,包括C++的标准模版库的应用、较为复杂的模拟题的训练、差分约束系统的建立和求解、最小费用最大流、双连通...

    北大acm试题

    poj1837和poj1276是背包问题的实例,而型如下表的简单DP问题,如poj3267、poj1836、poj1260和poj2533,以及最长公共子序列问题(如poj3176、poj1080和poj1159)都是动态规划的典型应用。 六、数学 数学在编程竞赛中...

    ACM常用算法及其相应的练习题 (2).pdf

    例题:poj3267、poj1836、poj1260、poj2533。 六、数学 * 组合数学:组合数学是指研究counting和enumeration的数学分支。例题:poj3252、poj1850、poj1019、poj1942。 * 数论:数论是指研究整数和其他数学对象的...

    算法训练方案详解

    - **示例题目**: POJ 3267, POJ 1836, POJ 1260, POJ 2533, POJ 3176, POJ 1080, POJ 1159 - **注意事项**: 理解每种模型的状态定义和转移方程。 #### 六、数学 **1. 组合数学** - **定义**: 研究组合结构的...

    acm新手训练方案新手必备

    - POJ 2533: 背包问题的特殊应用 - **编辑距离**:用于计算两个字符串之间的最小编辑距离。 - **示例题目**: - POJ 3176: 编辑距离问题 - POJ 1080: 编辑距离的变种 - POJ 1159: 编辑距离的复杂案例 #### 三...

    ACM算法总结--最新总结的ACM算法

    2. **区间DP**(如poj3267, poj1836, poj1260, poj2533):涉及区间状态的动态规划,如股票买卖最佳时机、矩阵链乘积等。 3. **矩阵链乘法**(如C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}):求解多个矩阵相乘时的最优顺序...

    LeetCode判断字符串是否循环-Leetcode:刷!

    2533 POJ 1836 Leetcode 70 Leetcode 309 搜索 DFS POJ 2488 POJ 3083 POJ 3009 POJ 1321 BFS POJ 3278 POJ 1426 POJ 3126 POJ 3414 POJ 2251 简单搜索技巧和剪枝 POJ 1010 :star: POJ 2362 POJ 1011(搜索+剪枝) ...

    北大POJ部分题目答案(一些基础题目)

    很多的POJ题目答案!1000~1008,1011~1014,1016,1017,1019,1028,1032,1045,1046,1047,1050,1061,1067,1068,1088,1102,1159,1163,1183,1207,1218,1226,1247,1256,1258,1298,1316,1323,...

Global site tag (gtag.js) - Google Analytics