最大单调递增子序列

来源:互联网 发布:网络教育大专收费 编辑:程序博客网 时间:2024/05/16 07:35

单调递增子序列(二)

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
描述

给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序列,并求出其长度。

如:1 9 10 5 11 2 13的最长单调递增子序列是1 9 10 11 13,长度为5。

输入
有多组测试数据(<=7)
每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的下一行里有n个整数,表示数列中的所有元素.每个整形数中间用空格间隔开(0<n<=100000)。
数据以EOF结束 。
输入数据保证合法(全为int型整数)!
输出
对于每组测试数据输出整形数列的最长递增子序列的长度,每个输出占一行。
样例输入
71 9 10 5 11 2 1322 -1
样例输出
51

来源


解题思路:用dp[m]表示以第m个元素为结尾的最长单调递增子序列的长度。也就是说你每次都以第i个数为结尾,找他的最大递增子序列,遍历时当第i个数大于他前面的数,那么他也继承了那个数的单调递增子序列。状态转移方程:dp[m]=max(dp[i],dp[k]+1);

下面的这个代码会超时,等过段时间我再更新更优秀的算法解决这个问题。

#include <stdio.h>#include <algorithm>#include <string.h>#define inf -0x3fffffff#define N 100010using namespace std;int a[N], dp[N];int main(){int i, j, n, Max,flag;while(~scanf("%d", &n)){flag=inf;memset(dp,0,sizeof(dp));dp[1]=1;for(Max=0, i=1; i<=n; i++){scanf("%d", &a[i]);if(a[i]<=flag)continue;for(j=1; j<i; j++){if(a[j]<a[i]){dp[i]=max(dp[i],dp[j]+1);//以最后一个元素为最大元素,和前面的元素一一对比,比当前元素小的加进去。 }}if(dp[i]>Max){Max=dp[i];flag=a[i];} }printf("%d\n", Max);} } 


0 0