7、牛牛现在有一个n个数组成的数列,牛牛现在想取一个连续的子序列,并且这个子序列还必须得满足:最多只改变一个数,就可以使得这个连续的子序列是一个严格上升的子序列,牛牛想知道这个连续子序列最长的长度是多少。

牛牛现在有一个n个数组成的数列,牛牛现在想取一个连续的子序列,并且这个子序列还必须得满足:最多只改变一个数,就可以使得这个连续的子序列是一个严格上升的子序列,牛牛想知道这个连续子序列最长的长度是多少。 

输入描述:
输入包括两行,第一行包括一个整数n(1 ≤ n ≤ 10^5),即数列的长度;
第二行n个整数a_i, 表示数列中的每个数(1 ≤ a_i ≤ 10^9),以空格分割。



输出描述:
输出一个整数,表示最长的长度。

 

输入例子:
6 
7 2 3 1 5 6

 

输出例子:
5

思路:
left数组表示正着求以每个元素作为结尾的最长递增子序列的长度
right数组表示逆着以每个元素作为开头的连续最长递增子序列的长度值

以元素2为例,我们发现以7结尾的最长的连续递增子序列的长度为left[0],而以3开头的连续递增子序列长度为right[2]。只要2前面的数7能够严格小于2后面的数3,说明通过改变7和3之间这个数至合适的数值则,这两部分就可以连成一个连续的严格递增子序列。寻找满足条件的最大的长度再加1即可。
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #define N 100000
 4 
 5 int main(){
 6     int n;
 7     int a[N];
 8     int right[N]; int left[N];
 9     scanf("%d",&n);
10     for(int i=0;i<n;i++)
11         scanf("%d",&a[i]);
12         
13     left[0]=1;
14     for(int i=1;i<n;i++){
15         ;
16         if(a[i]>a[i-1]){
17             left[i]=left[i-1]+1;
18         }else left[i]=1;
19     }
20     
21     right[n-1]=1;
22     for (int i = n-2; i >=0 ; i--) {  
23             if(a[i] < a[i+1])  
24                 right[i] = right[i+1]+1;  
25             else  
26                 right[i] = 1; 
27     }
28 
29 //输出表格,此题不需要这段输出    
30     for(int i=0;i<n;i++)
31         printf("%d ",left[i]);
32         printf ("\n");
33     for(int i=0;i<n;i++)
34         printf("%d ",right[i]);
35     
36     int max=1;
37     for (int i = 1; i <n-1; i++) {  
38             int l= left[i-1];  
39             int r = right[i+1];  
40             if(a[i-1] < a[i+1] && l+r > max)  
41                 max =l+r;  
42         }
43     printf("%d",max+1); 
44 }
45 
46         

 

posted on 2017-06-11 10:51  olive_gyr  阅读(1174)  评论(0编辑  收藏  举报