最长升序列求解(OJ 1093)
2011-04-15 16:41
363 查看
bupt acm oj: 1093
最长升序列 Submit: 1370 Accepted:446 Time Limit: 1000MS Memory Limit: 65536KDescription
给出一个序列,求出此序列的最长升序列。
Input
第一行有一个正整数T(T < 10),表示测试数据的数量。
每组测试数据一行,先给出一个正整数n(n < 300),接下来是n个正整数组成的序列,求此序列的最长升序列。
Output
每组测试数据占一行,输出一个正整数s,表示最长升序列的长度
Sample Input
2
4 1 2 2 4
4 2 4 2 6
Sample Output
3
3
上面该题就是求解最长升序列,自己先做了一遍,是WA,还觉得是服务器判断错误,发现是自己读题错误。原来我在求解时候只要发现有元素大于之前的最大元素就加入到最长升序子序列,这样是不正确的,例如24346,最长升序应该是2346,而按照我的做法变成了246,少了。发现这个问题,没我想得那么简单,丢人啊~~
看了半天网上的算法,发现对动态规划算法算是看明白了。这里Mark一下。
设f(i)表示L中以ai为末元素的最长递增子序列的长度。则有如下的递推方程:
这个递推方程的意思是,在求以ai为末元素的最长递增子序列时,找到所有序号在L前面且小于ai的元素aj,即j<i且aj<ai。如果这样的元素存在,那么对所有aj,都有一个以aj为末元素
的最长递增子序列的长度f(j),把其中最大的f(j)选出来,那么f(i)就等于最大的f(j)加上1,即以ai为末元素的最长递增子序列,等于以使f(j)最大的那个aj为末元素的递增子序列最末再加上ai;如果这样的元素不存在,那么ai自身构成一个长度为1的以ai为末元素的递增子序列。
if(a[j]<a[i] && b[j]+1>b[i]) b[i]=b[j]+1;//b[j]+1>b[i]保证了b[j]是i-1之前的最长升序长度
最长升序列 Submit: 1370 Accepted:446 Time Limit: 1000MS Memory Limit: 65536KDescription
给出一个序列,求出此序列的最长升序列。
Input
第一行有一个正整数T(T < 10),表示测试数据的数量。
每组测试数据一行,先给出一个正整数n(n < 300),接下来是n个正整数组成的序列,求此序列的最长升序列。
Output
每组测试数据占一行,输出一个正整数s,表示最长升序列的长度
Sample Input
2
4 1 2 2 4
4 2 4 2 6
Sample Output
3
3
上面该题就是求解最长升序列,自己先做了一遍,是WA,还觉得是服务器判断错误,发现是自己读题错误。原来我在求解时候只要发现有元素大于之前的最大元素就加入到最长升序子序列,这样是不正确的,例如24346,最长升序应该是2346,而按照我的做法变成了246,少了。发现这个问题,没我想得那么简单,丢人啊~~
看了半天网上的算法,发现对动态规划算法算是看明白了。这里Mark一下。
设f(i)表示L中以ai为末元素的最长递增子序列的长度。则有如下的递推方程:
这个递推方程的意思是,在求以ai为末元素的最长递增子序列时,找到所有序号在L前面且小于ai的元素aj,即j<i且aj<ai。如果这样的元素存在,那么对所有aj,都有一个以aj为末元素
的最长递增子序列的长度f(j),把其中最大的f(j)选出来,那么f(i)就等于最大的f(j)加上1,即以ai为末元素的最长递增子序列,等于以使f(j)最大的那个aj为末元素的递增子序列最末再加上ai;如果这样的元素不存在,那么ai自身构成一个长度为1的以ai为末元素的递增子序列。
#include<stdlib.h> #include<stdio.h> #define SIZE 300 int a[SIZE]; int b[SIZE]; int main() { int t; int n; scanf("%d",&t); if(t<0 || t>=10) return 0; for(int i=0;i<t;i++){ scanf("%d",&n); for(int j=0;j<n;j++) scanf("%d",&a[j]); b[0]=1; for(int i=1;i<n;i++){ b[i]=1; for(int j=0;j<i;j++) { if(a[j]<a[i] && b[j]+1>b[i]) b[i]=b[j]+1; } } int max=b[0]; for(int k=1;k<n;k++) if(max<b[k]) max=b[k]; printf("%d/n",max); } system("pause"); return 0; }
if(a[j]<a[i] && b[j]+1>b[i]) b[i]=b[j]+1;//b[j]+1>b[i]保证了b[j]是i-1之前的最长升序长度
相关文章推荐
- 最长递增子序列(LIS)求解
- D psd面试 (动态规划求解最长回文子序列)
- 求解最长不重复子序列(后缀数组)
- 九度OJ 1342:寻找最长合法括号序列II (DP)
- 求解最大子序列、最长递增子序列、最长公共子串、最长公共子序列
- 华为OJ(最长公共子串及公共最长子序列)
- 求解数组中最长递增自序列
- 九度OJ 1533 最长上升子序列 -- 动态规划
- 九度OJ 1342:寻找最长合法括号序列II (DP)
- O(nlgn)求解最长上升子序列长度
- 如何用O(nlogn)的的速度求解最长上升(下降)子序列
- 最长递增子序列问题的求解(LIS)
- 九度OJ 1533 最长上升子序列 -- 动态规划
- 最长子序列的问题求解
- OJ1306-最长公共子上升序列【dp】
- 最长递增子序列问题的求解
- AOJ-AHU-OJ-189 最长递增子序列(DFS)
- POJ 2533 最长上升子序列长度的求解 DP实现
- 初识动态规划算法,求解最长非递增子序列【DP算法】
- 动态规划求解最长公共子串与公共子序列