nyoj 214-单调递增子序列(二) (演算法,PS:普通的动态规划要超时)

214-单调递增子序列(二)

内存限制:64MB
时间限制:1000ms
Special Judge: No

accepted:11
submit:35

题目描述:

给定一整型数列{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

分析:  1、如果给的串本身是升序的,就直接加入进来temp[]串中  2、否则的话我们要找到第一个大于等于该值的位置,并改变该位置的值(使最终组成的temp[]串ASCⅡ码之和最小)

核心代码:
 1 while(m --)
 2 {
 3     scanf("%d", &v);
 4     if(temp[cnt] < v)
 5     {
 6         temp[++cnt] = v;
 7         continue;
 8     }
 9     for(int i = 0; i <= cnt; ++ i)
10     {
11         if(temp[i] >= v)
12         {
13             temp[i] = v;
14             break;
15         }
16     }
17 }

C/C++代码实现(AC):

 
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <stack>
 7 #include <map>
 8 #include <queue>
 9 #include <set>
10
11 using namespace std;
12 const int MAXN = 100010;
13
14 int main()
15 {
16
17     int t, A[MAXN], temp[MAXN], cnt;
18     while(~scanf("%d", &t))
19     {
20         cnt = 0;
21         memset(A, 0, sizeof(A));
22         memset(temp, 0, sizeof(temp));
23         scanf("%d", &A[0]);
24         temp[cnt] = A[0];
25         for(int i = 1; i < t; ++ i)
26         {
27             scanf("%d", &A[i]);
28             if(temp[cnt] < A[i])
29             {
30                 temp[++cnt] = A[i];
31                 continue;
32             }
33             for(int j = 0; j <= cnt; ++ j)
34                 if(A[i] <= temp[j])
35                 {
36                     temp[j] = A[i];
37                     break;
38                 }
39
40         }
41         printf("%d\n", cnt + 1);
42     }
43     return 0;
44 }

C/C++代码(TLE)<动态规划>:



 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <stack>
 7 #include <map>
 8 #include <queue>
 9 #include <set>
10
11 using namespace std;
12 const int MAXN = 100010;
13
14 int main()
15 {
16
17     int t, A[MAXN], dp[MAXN], cnt;
18     while(~scanf("%d", &t))
19     {
20         cnt = 0;
21         memset(A, 0, sizeof(A));
22         memset(dp, 0, sizeof(dp));
23         for(int i = 0; i < t; ++ i)
24         {
25             scanf("%d", &A[i]);
26             dp[i] = 1;
27             for(int j = 0; j < i; ++ j)
28                 if(A[i] > A[j])
29                     dp[i] = max(dp[i], dp[j] + 1);
30             cnt = max(cnt, dp[i]);
31         }
32         printf("%d\n", cnt);
33     }
34     return 0;
35 }

 

原文地址:https://www.cnblogs.com/GetcharZp/p/9102649.html

时间: 2024-10-28 14:46:45

nyoj 214-单调递增子序列(二) (演算法,PS:普通的动态规划要超时)的相关文章

nyoj 214 单调递增子序列(二) 【另类dp】

单调递增子序列(二) 时间限制: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<=1

nyoj 214——单调递增子序列(二)——————【二分搜索加dp】

单调递增子序列(二) 时间限制: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<=10

NYOJ 214 单调递增子序列(二)

单调递增子序列(二) 时间限制: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<=1

nyist oj 214 单调递增子序列(二) (动态规划经典)

单调递增子序列(二) 时间限制: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<=1

NYOJ 214 单调递增子序列nlogn

普通的思路是O(n2)的复杂度,这个题的数据量太大,超时,这时候就得用nlogn的复杂度的算法来做,这个算法的主要思想是只保存有效的序列,即最大递增子序列,然后最后得到数组的长度就是最大子序列.比如序列7 8 9 1 2 3 来说, 就是先把第一个数输入到数组中,然后继续输入后面的数,每输入一个数都要和最后一个数比较,因为这时最后一个数一定是有效序列中最大的,如果大于最后一个数,那么就直接将它放到数组的最后就行了,如果不大于最后一个数的话,就找到第一个比他大的数,然后替换它,样例中,先输入进去7

NYOJ 214 单调递增子序列(二)

#include<stdio.h>#include<string.h>const int maxn=100001;int dp[maxn],a[maxn];int Binary_search(int len,int k){ // 查找比第一个比dp[i]小或者是相等的位置 int start,end,mid; start=1; end=len; while(start<=end) { mid=(start+end)>>1; if(k==dp[mid]) retur

南阳ACM~~214单调递增子序列(二)

刚开始做这题的时候,以为是简单的动态规划,后来提交之后发现超时了,看到了N可以达到100000,用简单的动态规划,时间复杂度达到了N^2,明显会超时. 想了挺久的,还是不知道怎么做,百度了一下,才知道了原来运用二分搜索,把问题简化成类似排序,时间复杂度为logN,就不会超时了. 下面是AC的代码,看注释可以很容易理解的.如说的有错,欢迎指正. #include <iostream> #include <stdio.h> #include <cstring> using

nyoj 单调递增子序列(二)

单调递增子序列(二) 时间限制: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<=10

单调递增子序列(二)(南阳oj214)

单调递增子序列(二) 时间限制: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<=1