CSU 1047 最长上升子序列(线性dp)

版权声明:本文为博主原创文章,欢迎转载。如有问题,欢迎指正。 https://blog.csdn.net/weixin_42172261/article/details/89841500

最长上升子序列
这类动规问题可以从规模比现在小的情况下开始,而在规模较小的情况下还有规模更小的情况,一直到只有一个点。也就是以每个点为终点的最长上升子序列的长度都是1。然后对于某一个点,遍历从下标为1到这个点的前一个点的数,如果比它下,那么以这个点为终点的最长上升子序列的长度就可以加1了。
最终代码思路为:初始化每个dp数组下标的值都为1,然后对于每个点来说,都可以用它前面的几个点来更新,如果这个值比他前面的某个值要大,那么以这个点为终点的长度加1。
这个问题向外延伸出最长不下降子序列,最长下降子序列等等。

名词解释
一串数字比如1、5、3、6、9、8、10,它的子序列是从左到右不连续的若干个数,比如1、5、6,3、9、8、10都是它的子序列。
最长上升子序列即从左到右严格增长的最长的一个子序列,1、5、6、9、10就是这个序列的一个最长上升子序列。
给出若干序列,求出每个序列的最长上升子序列长度。
Input
多组数据,每组第一行正整数n,1 <= n <= 1000,第二行n个空格隔开的不大于1,000,000的正整数。
Output
每组数据输出一行,最长上升子序列的长度。
Sample Input
7
1 5 3 6 9 8 10
Sample Output
5

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

int a[1005], dp[1005];
int n;
int main()
{
	while (scanf("%d", &n)!=EOF){
		for (int i=1; i<=n; i++){
			scanf("%d", &a[i]);
			dp[i]=1;
		}
		for (int i=1; i<=n; i++){
			for (int j=1; j<i; j++){
				if (a[i]>a[j])
					dp[i]=max(dp[i], dp[j]+1);
			}
		}
		int maxx=0;
		for (int i=1; i<=n; i++)
			maxx=max(maxx, dp[i]);
		printf("%d\n", maxx);
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_42172261/article/details/89841500
今日推荐