百练 2757:最长上升子序列

这个之前有过lower_bound的 NlogN解法,这里所写的方法主要是为了练习动态规划DP的使用

这里的思路是,在这个位置之前找到比这个位置小的元素,获取其maxLen的值,找到一个最大的 加上1 之后把这个值赋值给maxLen[i] 

题目链接

//最长上升子列,O(N^2)的,动态规划解法
#include <iostream>
#include <cstring>
#include <algorithm>
#define maxn 1005
using namespace std;

int n;
int a[maxn];
int maxLen[maxn];

int main(void)
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
		maxLen[i] = 1;//对于单个元素,状态转移出的状态应该输出1 即对于单调递减序列输出1 
	}
	int maxx;
	for(int i=1;i<n;i++)
	{
		maxx = 2;
		for(int j=0;j<i;j++)
		{
//			if(a[i]>a[j]) //和前边的每一个进行比较,等于说从前边找到一个记录到的最大值
//			//如果后边大于前边的  这种写法体现出了DP的思路,但是比较隐式 
//			{
//				maxLen[i] = max(maxLen[i],maxLen[j]+1);  
//			}	
			
			//将上述if替换一种写法
			if(a[i]>a[j])
			{
				if(maxLen[j]+1 >=maxx)//这里的等于号很关键  
				{
					maxx = maxLen[j]+1;
					maxLen[i] = maxx;
				}
			} 
			//这里的思路是,在这个位置之前找到比这个位置小的元素,获取其maxLen的值,找到一个最大的 加上1 之后把这个值赋值给maxLen[i] 
		}	
	} 
//	for(int i=0;i<n;i++)
//	{
//		printf("%d\t",maxLen[i]);
//	}
	printf("%d",*max_element(maxLen,maxLen+n));
	//这种思想 即是每次找到以当前位置的最长上升子序列并记录下来
	//属于隐藏的,DP解法 
	//这个位置的最长上升子列,等于之前的最长上升子列与 某个位置+1的最大值 
} 

还有一个可以学习的STL应用 *max_element(a,a+n)返回这个数组中的最大值

猜你喜欢

转载自blog.csdn.net/curiousliu/article/details/81177447