【简单DP】 最长上升子序列(个数)

时间:2022-12-15 22:10:27

Description

A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1a2, ..., aN) be any sequence (ai1ai2, ..., aiK), where 1 <= i1 < i2 < ... < iK <= N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has ordered subsequences, e. g., (1, 7), (3, 4, 8) and many others. All longest ordered subsequences are of length 4, e. g., (1, 3, 5, 8).

Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.

Input

The first line of input file contains the length of sequence N. The second line contains the elements of sequence - N integers in the range from 0 to 10000 each, separated by spaces. 1 <= N <= 1000

Output

Output file must contain a single integer - the length of the longest ordered subsequence of the given sequence.

Sample Input

7
1 7 3 5 9 4 8

Sample Output

4

是求出上升(递增)序列的个数,所以如果第i项代表当前子序列的终点,那么要满足前j项(1<=j<=i-1)每一项都要小于第i项,再对j作为终点分解;最终状态就是,一个数的最长上升子序列就是自己,个数为1;两个的话如果不是递增就是自己,是递增则为终点+前一项的个数;

所以状态为:

1~n : dp[i] = 1 ;

1~i-1 :   if(a[i]>a[j])  dp[i] = max (dp[i] , dp[j] + 1 ) ;

得到的dp[i] 就是所有子序列的最大值,挨个比较即可; 


AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std ;
int dp[2000] ,a[2000];
int main() {
int n ;
while(cin>>n)
{
memset(dp,0,sizeof(dp));
memset(a,0,sizeof(a));
if(n==0) printf("1\n");
else
{
for(int i = 1 ; i<=n ; i++)
{
cin>>a[i];
}
int maxi = -999999 ;
for(int i = 1 ; i<=n; i++)
{
dp[i] = 1 ; //*第i项为终点至少有1个;
for(int j = 1 ; j <= i -1 ; j++)
{
if(a[i]>a[j])
{
dp[i] = max(dp[i] , dp[j] + 1 );
}
}
}
for(int i = 1 ; i <= n ; i++)
{
if(dp[i]>maxi)
maxi = dp[i];
}
cout << maxi <<endl;
}

}
return 0 ;
}