`
cm14k
  • 浏览: 31419 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

动态规划之最长单调递增子序列

阅读更多

问题描述:
找出由n个数组成的序列的最长单调递增子序列

解法一:

原序列记为X,对n个数递增排序,构造一个新序列Y, 对X,Y求其最长公共子序列即可.

/*
 * description: 最长单调递增子序列
 * 问题描述:
 * 找出由n个数组成的序列的最长单调递增子序列
 * 算法设计:
 * 解法一:
 * 原序列记为X,对n个数递增排序,构造一个新序列Y, 对X,Y求其最长公共子序列即可.
 * 
 * auther:cm
 * date:2010/11/17
 */
import java.util.LinkedList;
import java.util.List;
public class LISLength 
{
	private int[] arrX;
	private int[] arrY;
	private int[][] c;

	public LISLength(int[] arr)
	{
		arrX = new int[arr.length + 1];
		arrY = new int[arr.length + 1];
		System.arraycopy(arr,0,arrX,1,arr.length);
		System.arraycopy(arr,0,arrY,1,arr.length);
		selectSort(arrY, arrY.length - 1);
		lisLength();
	}

	//计算最长公共子序列
	public void lisLength()
	{
		c = new int[arrX.length][arrY.length];

		for (int i = 1; i < arrX.length; i++)
		{
			for (int j = 1; j < arrY.length; j++)
			{
				if (arrX[i] == arrY[j])
				{
					c[i][j] = c[i-1][j-1] + 1;
				}
				else
				{
					c[i][j] = max(c[i-1][j], c[i][j-1]);
				}
			}
		}
	}

	//返回最长单调递增子序列
	public List<Integer> getLIS()
	{
		LinkedList<Integer> list = new LinkedList<Integer>();
		int i = arrX.length - 1;
		int j = arrY.length - 1;
		while (i >= 1 && j >= 1)
		{
			if (arrX[i] == arrY[j])
			{
				list.addFirst(Integer.valueOf(arrX[i]));
				i--;
				j--;
			}
			else
			{
				if (c[i-1][j] > c[i][j-1])
				{
					i--;
				}
				else
				{
					j--;
				}
			}
		}
		return list;
	}

	private int max(int m, int n)
	{
		return m > n ? m : n;
	}

	//选择排序,0号空间不用
	private void selectSort(int[] a, int n)
	{
		for (int i = 1; i < n; i++)
		{
			int k = i;
			for (int j = i + 1; j <= n; j++)
			{
				if (a[k] > a[j])
				{
					k = j;
				}
			}
			if (k != i)
			{
				int temp = a[k];
				a[k] = a[i];
				a[i] = temp;
			}
		}
	}

	public static void main(String[] args) 
	{
		int[] arr = {4, 2, 3, 1, 8};
		//int[] arr = {8,9,10,2,3,4,5,6};
		LISLength lis = new LISLength(arr);
		List<Integer> a = lis.getLIS();
		for (Integer item: a)
		{
			System.out.print(item + " ");
		}
	}
}

序列X={4, 2, 3, 1, 8}

执行结果:

2 3 8

 

解法二:
1)用一个数组b[n]记录以a[i]结尾的最长单调递增子序列的长度;
2)序列的a的最长单调子序列的长度为max{b[i],0=<i<n};
3)b[i] = max{b[k],a[k]<=a[i]&&0=<k<i} + 1 ,b[0] = 1;

/*
 * description:最长单调递增子序列
 * 问题描述:
 * 找出由n个数组成的序列的最长单调递增子序列
 * 算法设计:
 * 解法二:
 * 1)用一个数组b[n]记录以a[i]结尾的最长单调递增子序列的长度;
 * 2)序列的a的最长单调子序列的长度为max{b[i],0=<i<n};
 * 3)b[i] = max{b[k],a[k]<=a[i]&&0=<k<i} + 1 ,b[0] = 1;
 * 
 * auther:cm
 * date:2010/11/17
 */
public class LIS
{
	private int[] a;
	private int[] b;

	public LIS(int[] a)
	{
		this.a = a;
		b = new int[a.length];
	}

	public void lis()
	{
		b[0] = 1;

		for (int i = 0; i < a.length; i++)
		{
			int k = 0;
			for (int j = 0; j < i; j++)
			{
				if (a[j] <= a[i] && k < b[j])
				{
					k = b[j];
				}
			}
			b[i] = k + 1;
		}
		int k = max(b);
                //输出结果
		print(k);
	}

	//求数组中最大值下标
	private int max(int[] b)
	{
		int max = b[0];
		int k = 0;
		for (int i = 0; i < b.length; i++)
		{
			if (max < b[i])
			{
				max = b[i];
				k = i;
			}
		}
		return k;
	}

	//输出
	public void print(int k)
	{
		for (int i = k - 1; i >= 0; i--)
		{
			if (b[k] == b[i] + 1 && a[i] <= a[k])
			{
				print(i);
				break;
			}
		}
		System.out.print(a[k] + " ");
	}

	public static void main(String[] args) 
	{
		int[] a = {4, 2, 3, 1, 8};
		LIS lis = new LIS(a);
		lis.lis();
	}
}

序列X={4, 2, 3, 1, 8}

执行结果:

2 3 8

 

分享到:
评论

相关推荐

    动态规划:最长单调递增子序列

    ### 动态规划:最长单调递增子序列 在计算机科学和算法设计中,动态规划是一种重要的技术,用于解决优化问题。本篇文章将详细介绍如何利用动态规划求解一个经典问题——寻找给定序列中的最长单调递增子序列...

    动态规划问题-最长单调递增子序列问题

    L={a1,a2,a3,…,an},是由n个不同的实数组成的序列,求L的最长单调递增子序列的长度(下标可不连续)

    最长单调递增子序列(O(n2)).rar_company7ne_最长单调递增子序列(动态规划法)

    总结来说,最长单调递增子序列问题可以通过动态规划法在O(n^2)的时间复杂度内解决,这种方法既高效又易于理解,广泛应用于算法竞赛和软件开发中。通过理解和掌握这种算法,程序员可以解决许多序列处理问题,提高代码...

    最长单调递增子序列

    用动态规划方法找出由n个数a【i】(1)组成的序列的一个最长单调递增子序列

    算法之动态规划---单调递增子序列

    根据给定的文件信息,我们将深入探讨两个关键的IT领域知识点:动态规划在寻找最长单调递增子序列中的应用以及动态规划在图像压缩算法中的作用。 ### 一、动态规划与最长单调递增子序列 #### 知识点概述: **最长...

    最长的单调递增子序列

    总结来说,这段代码通过动态规划的方法有效地解决了寻找最长单调递增子序列的问题,其核心在于利用辅助数组`D`记录到达每个位置时的最长递增子序列长度,并通过不断更新最大长度和对应下标找到最终答案。这种方法的...

    LIS最长单调递增子序列

    最长单调递增子序列(Longest Increasing Subsequence, LIS)是计算机科学中一种经典的问题,主要涉及算法设计和分析,特别是在动态规划领域的应用。在这个问题中,我们需要在给定的一个整数序列中找出一个尽可能长...

    单调递增序列

    设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。

    最长递增子序列

    算法导论,请给出一个O(n^2)时间的算法,使之能找出n个数的序列中最长的单调递增子序列

    单调递增子序列

    最长单调递增子序列,运行时间为O(nlgn),为算法导论上的算法

    中科大算法导论课程实验 最长递增子序列 报告

    动态规划方法的核心在于为每一个子序列维护一个最长递增子序列的长度,通过比较和更新每个元素所能构成的最长递增子序列来得到整个序列的最长递增子序列。该方案具有较好的时间复杂度和空间复杂度,适用于较大规模的...

    最长递增子序列的求法

    最长递增子序列问题是一个很基本、较常见的小问题,但这个问题的求解方法却并不那么显而易见,需要较深入的思考和较好的算法素养才能得出良好的算法。由于这个问题能运用学过的基本的算法分析和设计的方法与思想,...

    求取最长递增子序列(MFC编程)

    动态规划通过构建一个数组,记录到当前位置为止的最长递增子序列的长度。这个数组通常被称为DP数组。对于每个元素,我们检查在其之前的所有元素,如果当前元素大于前一个元素,且与前一个元素构成的子序列更长,就...

    最长单调递增子序列LIS

    我写的LIS算法,有两种思路,程序全在这个cpp文件中,可以运行

    单调递增子序列 最大连续子段和

    单调递增子序列(Longest Increasing Subsequence, LIS) **定义**:在数组或序列中找到最长的子序列,使得该子序列中的元素按顺序严格递增。 **应用场景**: - 在算法竞赛中,LIS 是一个非常常见的问题。 - 在...

    最长递增子序列1

    最长递增子序列(LIS)是数组或序列中一个重要的概念,它的目标是找到一个序列的最长子序列,使得这个子序列中的元素是严格递增的。在给定的描述中,我们看到了三种不同的方法来求解LIS问题。 **方法一:动态规划...

    js代码-求最长递增子序列

    总结来说,"js代码-求最长递增子序列"这个问题通过动态规划或单调栈的解决方案,展示了JavaScript在处理算法问题上的能力,同时为我们提供了一个优化空间和时间效率的典型示例。理解并掌握这种算法不仅有助于提高...

    动态规划算法的应用

    在本实验中,我们将使用动态规划算法来解决两个经典的问题:数塔问题和最长单调递增子序列问题。 数塔问题 数塔问题是动态规划算法的一个经典应用。该问题的描述如下:给定一个数塔,其存储形式为如下所示的下三角...

    动态规划算法中对子序列的一些模板

    2. **最长递增子序列(Longest Increasing Subsequence, LIS)** - LIS问题是在一个序列中找出最长的严格递增子序列。 - 动态规划解法:dp[i]表示以第i个元素结尾的LIS的长度。状态转移方程为dp[i] = max(dp[j] + ...

    动态规划解决算法0~1背包问题实验报告(含源代码).doc

    最长单调递增子序列问题是指,给定一个序列,找出该序列的最长单调递增子序列。该问题可以使用动态规划法和排序算法解决。 本实验报告展示了动态规划法解决0/1背包问题的实验结果,并讨论了其他几种算法在解决该...

Global site tag (gtag.js) - Google Analytics