1281:最长上升子序列
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 15871 通过数: 8180
【题目描述】
一个数的序列bibi,当b1<b2<...<bSb1<b2<...<bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1,a2,...,aN)(a1,a2,...,aN),我们可以得到一些上升的子序列(ai1,ai2,...,aiK)(ai1,ai2,...,aiK),这里1≤i1<i2<...<iK≤N1≤i1<i2<...<iK≤N。比如,对于序列(1,7,3,5,9,4,8),有它的一些上升子序列,如(1,7),(3,4,8)等等。这些子序列中最长的长度是4,比如子序列(1,3,5,8)。
你的任务,就是对于给定的序列,求出最长上升子序列的长度。
【输入】
输入的第一行是序列的长度N(1≤N≤1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000。
【输出】
最长上升子序列的长度。
【输入样例】
7
1 7 3 5 9 4 8
【输出样例】
4
【分析】
算法思想:请见
设f[i]表示以a[i]结尾的最长上升子序列。
(1)阶段:子序列结尾的位置,即 i 。
(2)状态:j=1...i,f[j]序列中的每个值都是状态。
(3)决策:a[i]是否加到序列中?
(4)策略:最大化上升子序列长度。
(5)状态转移方程:
(6)边界:f[1...n]=1
(7)目标:max(f[i])
#include <stdio.h>
#define MAXN 1010
int a[MAXN],f[MAXN]; //f[i]表示以a[i]为结尾的最长上升子序列的长度
int max(int x,int y)
{
return x > y ? x : y;
}
int main()
{
int n;
int i,j,ans=1;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
f[i]=1; // 初始化f[i]
}
// 动态更新f[i]
for(i=2;i<=n;i++)
{
for(j=1;j<i;j++)
{
if(a[i]>a[j])
f[i]=max(f[i],f[j]+1);
}
ans=max(ans,f[i]);
}
printf("%d\n",ans);
return 0;
}