您的位置:首页 > 其它

AOJ-AHU-OJ-189 最长递增子序列(DFS)

2014-03-12 14:30 363 查看
[align=center]最长递增子序列[/align]
[align=center]Time Limit: 1000 ms   Case Time Limit: 1000 ms   Memory Limit: 64 MB
[/align]
[align=center][/align]
Description
有n个互不相同的整数an

若存在一个数列bm

其中对于任何1 < i < m

满足bi < bi+1 且 abi < abi+1

则称abn为an的一个递增子序列

试求出给定序列的最长递增子序列长度

Input
本题由多组数据组成,以EOF结束
第2N+1行整数n,代表数组长度,1 <= n <= 7000
第2N+2行n个整数ai,0 <= ai <=231-1
Output
对于每组数据输出一行结果,代表最长递增序列长度

Sample Input
OriginalTransformed
3
1 2 3
10
3 18 7 14 10 12 23 41 16 24


Sample Output
OriginalTransformed
3
6


————————————————————激动的分割线————————————————————

思路:看到这一题,应该能想到,和滑雪其实是一样的。滑雪是二维的,它是一维的。自左向右,每次遇到递增的点,需要抉择走还是不走。每个结点向右DFS之后,保存了它能走的最长距离。DFS+记忆化搜索。

代码如下:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define Max(a, b) (a > b ? a : b)
int vis[7010];
int a[7010];
int len;
int dfs(int k){
if(vis[k])
return vis[k];//记忆化搜索
vis[k] = 1;
for(int d = 1; d < len; d++){//自然,方向是一路向右
int nk = k + d;
if(a[nk] > a[k] && nk < len)
vis[k] = Max(vis[k], dfs(nk) + 1);//某点可以走的话,该不该走?那么取MAX(它本身,走了该点之后的序列长度+1)
}
return vis[k];
}
int main(){
while(~scanf("%d", &len)){
int maxi = -1;
for(int i = 0; i < len; i++)
scanf("%d", a+i);
memset(vis, 0, sizeof(vis));
for(int i = 0; i < len; i++){
vis[i] = dfs(i);//对数列每个点进行dfs,如果已经记忆
maxi = Max(vis[i], maxi);//取最长的vis[]
}
printf("%d\n", maxi);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: