严格上升子序列 dp CF Round_FF div1 A

大家都很强, 可与之共勉。

【问题描述】
Mushroom手中有n个数排成一排,现在Mushroom想取一个连续的子序列,使得这个子序列满足:最多只改变一个数,使得这个连续的子序列是严格上升子序列,Mushroom想知道这个序列的最长长度是多少。
【输入格式】
第一行一个整数n,表示有n个数。
第二行为n个数。
【输出格式】
一个数,为最长长度。
【输入样例】
6
7 2 3 1 5 6
【输出样例】
5
【样例解释】
选择第2个数到第6个数,把1改变成4即可。

DP

正反两次DP

因为是严格上升
所以应该严格判断a[i] 与 a[i - 2] 的关系

#include "cctype"
#include "cstdio"

#define min(a, b)  ((a) < (b) ? (a) : (b))
#define max(a, b)  ((a) > (b) ? (a) : (b))

inline void readIn(unsigned int& x)  {
    static char ch;
    while ( !isdigit(ch = getchar()) );
    for (x = -48 + ch; isdigit(ch = getchar()); (x *= 10) += ch - 48);
}

const unsigned int MaxN = 100005;

unsigned int f[MaxN], a[MaxN], g[MaxN], ans, n;

int main()  {
    register int i;
    freopen( "seq.in", "r", &_iob[0] );
    freopen( "seq.out", "w", &_iob[1] );
    readIn ( n );
    for ( i = 0; i ^ n; readIn( a[++i] ) );
    for ( i = 1; i <= n; ++i ) f[i] = ( a[i] > a[i - 1] ) ?  f[i - 1] + 1 : 1;
    for ( i = n; i >= 1; --i ) g[i] = ( a[i] < a[i + 1] ) ?  g[i + 1] + 1 : 1;
    for ( i = 1; i <= n; ++i )  ans = max( g[i] + 1, max( ans, f[i] + 1) );
    for ( i = 1; i <= n; ++i ) 
        (a[i + 1] >= a[i - 1] + 2)  ?  
            ans = max( ans, f[i - 1] + g[i + 1] + 1 ) : 1;
    printf ( "%d\n", ans );
}

你可能感兴趣的:(严格上升子序列 dp CF Round_FF div1 A)