牛牛现在有一个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 (" "); 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