-
时间:2016-04-13 23:39:47 星期三
-
题目编号:[2016-04-13][codeforces][447][C][DZY Loves Sequences]
-
题目大意:给定一串数字,问改变其中一个数字之和,最长能得到多长的严格增加的子串
-
分析:
- 维护每个数字往左和往右能延续多长(严格减,增),然后枚举每个点,
- 如果这个点已经在一个严格增加的序列中,那么ans =min(n, max(ans , l[i] + r[i] + 1)) 即左右两边延伸之后,改变后面非递增的一个数字
- 注意这种情况,i位置的数字两边必须相差1,这样i才有的改
- 如果这个点不在一个严格递增的序列中,那么就更改这个值
- 如果这个点已经在一个严格增加的序列中,那么ans =min(n, max(ans , l[i] + r[i] + 1)) 即左右两边延伸之后,改变后面非递增的一个数字
- 维护每个数字往左和往右能延续多长(严格减,增),然后枚举每个点,
//实现和上面讲得有点差异,但是原理一样
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 1E5 + 10;
int a[maxn],b[maxn],c[maxn],n;
int main(){
scanf("%d",&n);
for(int i = 1 ; i <= n ; ++i){
scanf("%d",&a[i]);
}
b[1] = 1;
for(int i = 2 ; i <= n ; ++i){
if(a[i] > a[i - 1]) b[i] = b[i - 1] + 1;
else b[i] = 1;
}
c[n] = 1;
for(int i = n ; i >= 2 ; --i){
if(a[i] > a[i - 1]) c[i - 1] = c[i] + 1;
else c[i - 1] = 1;
}
int ans = c[1]+1;
for(int i = 2 ; i < n ; ++i){
if(a[i - 1] < a[i] && a[i] < a[i + 1]){
ans = min(n,max(ans,b[i] + c[i]) );
}
if(a[i - 1] + 1 < a[i + 1])
ans = max(ans , b[i - 1] + c[i + 1] + 1);
}
ans = min(n,max(ans,b[n]+1));
printf("%d\n",ans);
return 0;
}
时间: 2024-12-28 14:03:28