题目
108.最长不降子序列 (15分)
C时间限制:1 毫秒 | C内存限制:3000 Kb
题目内容:
所谓子序列,就是在原序列里删掉若干个元素后剩下的序列,
以字符串"abcdefg"为例子,去掉bde得到子序列"acfg"现在的问题是,
给你一个数字序列,你要求出它最长的单调不降子序列。
输入描述
多组测试数据,每组测试数据第一行是n(1<=n<=10000),表示n个数据,
下一行是n个比10^9小的正整数输出描述
对于每组测试数据输出一行,每行内容是最长的单调不降子序列
的长度输入样例
5
1 2 4 8 16
5
1 10 4 9 7
9
0 0 0 1 1 1 5 5 5输出样例
5
3
9
解题思路:
动态规划思想
原数组为a[],另创一个数组dp,如果序列以a[i]结尾,其最长不降子序列的长度为dp[i]
首先给每个dp赋1表示本身成一个序列
从第二个数(63)开始遍历它前面的数,如果有小于等于它的就更新以下面数组为例
15 63 22 23
i=1时,遍历63前面的数,如果有小于等于它的就更新其dp,dp[1]=max(dp[0]+1,dp[1]:1)=2;
i=2时,遍历22前面的数,发现15<22,dp[2]=max(dp[0]+1,dp[2])=2;
i=3时,遍历23前面的数,发现15<21,dp[3]=max(dp[0]+1,dp[3])=2,发现22<23,dp[3]=max(dp[2]+1,dp[3]:2)=3,
最终得出最长不降子序列的长度为3
#include<iostream>
#include<stdio.h>
#define N 10005
using namespace std;
int a[N],dp[N];
int main()
{
int n,len=1;
while(cin>>n){
len=1;
for(int i=0;i<n;i++)
{
cin>>a[i];
dp[i]=1;
}
for(int i=1;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(a[j]<=a[i])//这里要加等号,因为是不降
{
dp[i]=max(dp[j]+1,dp[i]);
}
}
len=max(len,dp[i]);
}
//for(int i=0;i<n;i++)cout<<dp[i]<<" ";cout<<endl;
cout<<len<<endl;
}
return 0;
}