您的位置:首页 > 其它

动态规划(最长子序列)

2014-01-21 13:31 190 查看
寒假集训正式开始啦!希望队员们享受这段时光。


萝卜(yuanhanchun)

收件箱(0)注销


最长上升子序列



Time Limit: 3000ms   Memory limit: 65536K  有疑问?点这里^_^



题目描述

一个数的序列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



来源

动态规划解答:

将每个输入的数组与到此数组为止连续的升序子序列同步,然后用循环

求出最大值即可;

子问题:

每单位长度数列的升序子数列长度;

代码如下:

#include<stdio.h>

int main()

{
int i,j,a[1000],amax[1000],max,li,n; //可以减掉变量,但为了便于理解,加上变量 
scanf("%d",&n);

for(i=1;i<=n;i++)
scanf("%d",&a[i]);
amax[1]=1;
for(i=2;i<=n;i++)
{li=0;

for(j=1;j<i;j++)
if(a[i]>a[j])// 一定大于 
if(li<amax[j])li=amax[j]; 
//只加不减,只要满足条件就加1,限制在下方; 
amax[i]=li+1;

}

max=0;

for(i=1;i<=n;i++)
if(max<amax[i])max=amax[i];
printf("%d\n",max);
 
}

最长公共子序列:


1132:最长公共子序列分数: 4

时间限制:1 秒

内存限制:32 兆

特殊判题: 否

提交:4

解决: 2

题目描述

给你一个序列X和另一个序列Z,当Z中的所有元素都在X中存在,并且在X中的下标顺序是严格递增的,那么就把Z叫做X的子序列。

例如:Z=<a,b,f,c>是序列X=<a,b,c,f,b,c>的一个子序列,Z中的元素在X中的下标序列为<1,2,4,6>。

现给你两个序列X和Y,请问它们的最长公共子序列的长度是多少?

输入格式

输入包含多组测试数据。每组输入占一行,为两个字符串,由若干个空格分隔。每个字符串的长度不超过100。

输出

对于每组输入,输出两个字符串的最长公共子序列的长度。

样例输入

abcfbc abfcab

programming contest 

abcd mnp

样例输出

4

2

0

#include<stdio.h>
#include<string.h>
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int i,j,c[101][101],m,n,v;
char a[1001],b[1001];
while(scanf("%s%s",a,b)!=EOF)
{

m=strlen(a);
n=strlen(b);
v=m>n?m:n;
for(i=0;i<=v;i++)
{c[i][0]=0;
c[0][i]=0;}
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
{
if(a[i-1]==b[j-1])c[i][j]=c[i-1][j-1]+1;
else c[i][j]=max(c[i-1][j],c[i][j-1]);
}
printf("%d\n",c[m]
);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm