单调递增子序列(二)(nyoj 214)
2014-04-08 21:49
197 查看
单调递增子序列(二)
时间限制:1000 ms | 内存限制:65535 KB难度:4
描述
给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序列,并求出其长度。
如:1 9 10 5 11 2 13的最长单调递增子序列是1 9 10 11 13,长度为5。
输入有多组测试数据(<=7)
每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的下一行里有n个整数,表示数列中的所有元素.每个整形数中间用空格间隔开(0<n<=100000)。
数据以EOF结束 。
输入数据保证合法(全为int型整数)!
输出对于每组测试数据输出整形数列的最长递增子序列的长度,每个输出占一行。
样例输入
7 1 9 10 5 11 2 13 2 2 -1
样例输出
5 1
这个题我理解了有一会= =。
觉得这个写的还不错---->点击打开链接
程序中的dp数组不再是存一个数值来代表最大的长度,而是存储到目前为止的最长的递增子序列的那个序列,由下标k来控制,所以k的值就代表了递增子序列的长度。
#include <stdio.h> #define N 100010 int a , dp ; //dp[i]表示序列长度为i是序列的最后一个元素的最小值 void answer(int n) { int low, high, mid, i, k = 2; dp[1] = a[1]; for(i = 2; i <= n; i++) { if(dp[k - 1] < a[i])//如果a[i]比dp[k-1]大,那么就表示a[i]可以直接接在序列的后面构成新的序列 dp[k ++] = a[i]; else {//否则运用二分法较快速在dp[low]中找到a[i]能插入的地i方 //满足dp[low]<a[i]且low是满足条件的最大值 ,这样dp[low] < a[i] <= dp[low + 1],再将a[i]替换dp[low + 1],因为当子序列长度一样时,序列最后一 //个元素选择小的那个元素会产生更长的子序列 low = 1; high= k; while(low <= high) { mid = (low + high) / 2; if(a[i] < dp[mid]) high = mid - 1; else low = mid + 1; } //替换 dp[low] = a[i]; } } /* for(i = 1; i <= n; i++) printf("%d ", dp[i]); printf("\n"); */ printf("%d\n", k - 1); } int main (void) { int n; while(scanf("%d", &n) != EOF) { int i; for(i = 1; i <= n; i++) scanf("%d", &a[i]); answer(n); } return 0; }
相关文章推荐
- nyoj 214 单调递增子序列(二)
- NYOJ 题目214 单调递增子序列(二)(动态规划,二分)
- nyoj_214_单调递增子序列(二)_201403182131
- NYOJ214 单调递增子序列(二) 【动态规划】+【二分法】
- NYOJ-214 单调递增子序列(二) TLE 分类: NYOJ 2014-01-28 22:57 171人阅读 评论(0) 收藏
- nyoj 214——单调递增子序列(二)——————【二分搜索加dp】
- (NYoj 214)单调递增子序列(二) --非递归思想模板
- nyoj 214 单调递增子序列(二)【二分+DP】
- NYOJ 214 单调递增子序列 二
- nyoj-214-单调递增子序列(二)
- NYOJ 214.单调递增子序列(二)(动态规划)
- nyoj 214 单调递增子序列(二)《LIS》
- NYOJ-214 单调递增子序列(二) TLE
- NYOJ 214 单调递增子序列(二) (LIS模板)
- NYOJ 214 单调递增子序列(二)
- NYOJ214 单调递增子序列(二)(LIS)
- nyoj 214 - 单调递增子序列(二)
- NYOJ214单调递增子序列(二)【dp+二分查找】
- nyoj 214 单调递增子序列(二) dp+二分
- NYOJ 题目214 单调递增子序列(二) dp+二分