动态规划(最长子序列)

最长上升子序列

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

题目描述

一个数的序列bi,当b 1 < b 2 < ... < b S的时候,我们称这个序列是上升的。对于给定的一个序列(a 1, a 2, ..., a N),我们可以得到一些上升的子序列(a i1, a i2, ..., a iK),这里1<= i 1 < i 2 < ... < i K <= 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][n]);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值