1759:最长上升子序列
-
总时间限制:
- 2000ms 内存限制:
- 65536kB
-
描述
-
一个数的序列
bi,当
b1 <
b2 < ... <
bS的时候,我们称这个序列是上升的。对于给定的一个序列(
a1,
a2, ...,
aN),我们可以得到一些上升的子序列(
ai1,
ai2, ...,
aiK),这里1 <=
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
这是OpenJudge上的一道题目,戳我查看 ——————————分析———————————— 这是一道非常基础的dp题,采用了dp最常见的“人人为我”思想,接下来让我们看一看。 二维数组的方法就不介绍了,接下来我们来看一看一位数组(滚动数组)。 我们用a数组来表示原数组,b数组来表示从n开始到i字符的最长上升子序列。因此公式为:
if(a[j]>a[i]&&b[j]>b[i]) b[i]=b[j];
或者
b[i]=max(b[i],b[j]+1);
——————————代码——————————
觉得有用就顶起来#include<cstdio> int a[1005],b[1005],n,i,j,c[1005]={0};//c数组是用来输出的 int main() { int max,start; scanf("%d",&n); for(i=1;i<=n;i++)scanf("%d",&a[i]); b[n]=1; max=1; start=n; c[n]=-1; for(i=n-1;i>=1;i--) { for(j=i+1;j<=n;j++) if(a[j]>a[i]&&b[j]>b[i]) {b[i]=b[j];c[i]=j;} b[i]++; if(b[i]==1)c[i]=-1; if(b[i]>=max){max=b[i];start=i;} } printf("%d\n",max); /*do { if(c[start]==-1) printf("%d",a[start]); else printf("%d ",a[start]); start=c[start]; }这是输出部分 while(start!=-1);*/ return 0; }