时间: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才有的改
- 如果这个点不在一个严格递增的序列中,那么就更改这个值
//实现和上面讲得有点差异,但是原理一样#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;}