HDU 5532 Almost Sorted Array(最长不下降或不上升子序列)

题目:给你一个序列,问你,这个序列只减少一个元素,减少之后是否为不上升序列或者不下降序列。

思路:直接对序列求最长不下降和不上升子序列,如果这个子序列的长度为n-1或者n的话,就符合题目条件。

最长不下降子序列和最长不上升子序列:这里使用数据结构的方法求最长不上升(下降)子序列的长度。就是另外构造一个数组 f[] ,这个数组表示的意思是:f [ i ] 表示的是长度为 i 的子序列的最小(最大值),因为,同样长度的子序列,最后一个数字最小或最大的时候,更方便往后面放数字。这个时候可能会说就算我的这个数字足够小或者足够大,如果位置不对,那么以他为结尾的序列长度也不能是最长的。至于这个问题,其实,我们更新的是 f[] ,每次我们都从头到尾地扫 f[] ,更新这个数组,就不会出现那个问题了。

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<string.h>
 4 #include<math.h>
 5 #include<algorithm>
 6 #include<vector>
 7 #include<string>
 8 #include<queue>
 9 #include<map>
10 #include<stack>
11 #include<set>
12 #define ll long long
13 #define maxn 100010
14 #define PI acos(-1.0)    //圆周率
15 const int mod=1e9+7;
16 using namespace std;
17 int num[maxn];
18 int f[maxn];
19 int n;
20 int main()
21 {
22     int T;
23     scanf("%d",&T);
24     while(T--)
25     {
26         memset(f,0,sizeof(f));
27         memset(num,0,sizeof(num));
28 
29         scanf("%d",&n);
30         for(int i=0;i<n;i++)  scanf("%d",&num[i]);
31 
32         int len=1;
33         f[0]=num[0];
34         for(int i=1;i<n;i++)
35         {
36             if(num[i]>=f[len-1])  f[len++]=num[i];
37             else
38             {
39                 int cnt=upper_bound(f,f+len,num[i])-f;
40                 f[cnt]=num[i];
41             }
42         }
43 
44         if(len==n-1||len==n)
45         {
46             printf("YES
");
47             continue;
48         }
49 
50         len=1;
51         memset(f,0,sizeof(f));
52         f[0]=num[n-1];
53         for(int i=n-2;i>=0;i--)
54         {
55             if(num[i]>=f[len-1])  f[len++]=num[i];
56             else
57             {
58                 int cnt=upper_bound(f,f+len,num[i])-f;
59                 f[cnt]=num[i];
60             }
61         }
62 
63         if(len==n-1||len==n)  printf("YES
");
64         else  printf("NO
");
65     }
66 
67     return 0;
68 }
View Code
 
原文地址:https://www.cnblogs.com/2cm-miao/p/5869547.html