上升序列问题

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

int a[20005],d[20005];//a存放数组,d存放逆序的元素个数
/*  
    例如a数组为   3 4 1 2 3 6 
  d数组中存储为   3 2 4 3 2 1
*/

void main()
{
	int i,j;
	int n,m,length;
	scanf("%d",&n);//输入数组大小n
    for (i=1;i<=n;i++)
    {
		scanf("%d",&a[i]);//输入数据
    }
	scanf("%d",&m);//输入要查询m组序列

	for(i=n;i>=1;i--)
	{
		d[i]=1;
		for(j=n;j>i;j--)
		{
			if(a[i]<a[j] && d[i]<d[j]+1)
				d[i]=d[j]+1;//动态规划思想,求最长降序(逆序,降序)
		}
	}

	while(m--)
	{
		int temp=INT_MIN;
		int flag=0;
		scanf("%d",&length);
		for(i=1;i<=n;i++)
		{
			if(length<=d[i])
			{
				flag=1;
				break;
			}
		}
		if(flag==0)
			printf("Impossible\n");
		else
		{
			i=1;
			while(i<=n && length)
			{
				//当要查询的长度小于该数起始的数组长度时,并且后面的数要大于前面的数
				//才能保证升序,每次输出一个数后length-1.
				/*
				对于有解的情形 设要求的长度为len
				从头找到第一个使得d[i]>=len的i,这就是符合要求的LIS的第一个数;
				在i之后找到第一个使得d[j]>=len-1且a[j]>a[i]的j,这就是第二个数;
				在j之后找到第一个使得d[k]>=len-2且a[k]>a[j]的k,这就是第三个数;
				…… 依此类推
				*/
				if(length<=d[i] && a[i]>temp )
				{
					printf("%d ",a[i]);
					length--;
					temp=a[i];
				}
				i++;
			}
			printf("\n");
		}
	}
	system("pause");
}

ps.可以通过二分查找改进效率 达到O(nlogn)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值