zoukankan      html  css  js  c++  java
  • 最长上升子序列(Longest increasing subsequence)

    问题描述
            对于一串数A={a1a2a3an}它的子序列为S={s1s2s3sn},满足{s1<s2<s3<<sm}。求A的最长子序列的长度。

    大致的思路都是:

    动态规划法

    算法描述:
            设数串的长度为n,L[i]为以第i个数为末尾的最长上升子序列的长度,a[i]为数串的第i个数。
            L[i]的计算方法为:从前i-1个数中找出满足a[j]<a[i](1<=j<i)条件的最大的L[j],L[i]等于L[j]+1。
    动归表达式:

    但我想到了另外一种算法。

    假设这一组数列里面最大的数是max。。那么就是求以1到max为结尾的数列的最大长度。。比如1,4,6,8就是以8结尾的数列,他的长度是4。假设max在数列里面的位置是k。我们在位置k的左边找到了一个数据max-1。。那么,以max为结尾的最大数列的长度是不是就是以max-1为结尾的数列长度加一。同理,以max-1为结尾的最大数列的长度是不是就是以max-2为结尾的数列长度加一。这种规律一直到最后,就可以从以1为结尾的数列开始往上算。
     
    把这种思维简化成数据就是:
    设数串的长度为n,L[x]为以x为末尾的最长上升子序列的长度。x在数列中的位置为k。
    L[i]的计算方法为:从前k-1个数中找出满足a[i]<x(1<=i<k)条件的最大的L[i],L[k]等于L[i]+1。

    虽然代码写起来比刚才那个复杂一点点。但是个人认为相对来说比较好理解。

    #include "stdafx.h"
    #include <stdio.h>
    
     int main()
    {   
    
    	int a[7];
    	int max ;
    	int num ;
    	int len[1000] = {0};//先把长度数组赋0
    	int i, j,k;
    	int maxlen = 0;
    	int temp = 0;
    
    	scanf("%d",&num);
    
    	//先找出最大值,确定循环次数。
    		scanf("%d",&a[0]);
    	max = a[0];
    	for (i = 1; i < num; i++)
    	{
    		scanf("%d",&a[i]);
    		max = max>a[i]?max:a[i];
    	}
    
    	//计算以i为结尾的最长上升子序列的长度
    	for (i = 1; i <= max; i++)
    	{
    		temp = 0;//标记数列中是否存在这个数
    		for (j = num;j >= 0;j--)//找出数据i在数列中的位置,让j记录
    		{
    			if (a[j] == i) 
    			{
    				temp = 1;
    				break;
    			}
    		}
    		//如果数据i存在,则开始从i所在的位置往前寻找符合条件的长度
    		if(temp == 1)
    		{
    			for (k = j;k >= 0;k--)
    			{
    				if (a[k]<i&&len[a[k]]>len[i])//如果位置k(k<j)的数据小于i,比较以a[k]结尾的数列长度大于以i结尾的数列。那么,赋值过去。
    				{
    					len[i] = len[a[k]];
    				}
    			}
    			len[i]++;//以max为结尾的最大数列的长度就是以一个小于max的数结尾的最大数列长度加一
    			if (len[i] > maxlen)
    			{
    				maxlen = len[i];
    			}
    		}
    	}
    	printf("%d
    ",maxlen);
    	return 0;
    }


     

  • 相关阅读:
    ubuntu下查看某个头文件来自哪个软件包?
    系统调用fork()在powerpc上的源码分析
    linux应用程序如何从用户空间进入内核空间?
    执行docker ps时提示"dial unix /var/run/docker.sock: connect: permission denied"如何处理?
    ubuntu上安装远程桌面服务
    执行python安装命令时报错"ModuleNotFoundError: No module named 'setuptools'"如何处理?
    在arm下使用docker build创建容器镜像时磁盘空间不足如何处理?
    9、序列
    8、数据类型
    7、运算符与表达式
  • 原文地址:https://www.cnblogs.com/zkkkkkky/p/4423000.html
Copyright © 2011-2022 走看看