Pokémon Army (easy version)

72 阅读2分钟

题目链接

给出n个数 让你找到一个子序列 a j 1 − a j 2 + a j 3 − a j 4 + a j 5 . . . . . . a_{j1}-a_{j2}+a_{j3}-a_{j4}+a_{j5}... ... aj1​−aj2​+aj3​−aj4​+aj5​......和最大。

其实很快就想到过dp[i][2]记录前i个数两种状态结尾的最大值,不过没细想下去。

dp[i][1]表示前i个数以减号结尾的最大值,dp[i][0]表示前i个数以加号结尾的最大值

先处理出dp[i][0]为前i个数的最大值(也就是只选最大值以加号结尾)

然后有四种状态转移:
d p [ i ] [ 0 ] = m a x ( d p [ i ] [ 0 ] , d p [ i − 1 ] [ 0 ] ) dp[i][0]=max(dp[i][0],dp[i-1][0]) dp[i][0]=max(dp[i][0],dp[i−1][0])
d p [ i ] [ 0 ] = m a x ( d p [ i ] [ 0 ] , d p [ i − 1 ] [ 1 ] + a [ i ] ) dp[i][0]=max(dp[i][0],dp[i-1][1]+a[i]) dp[i][0]=max(dp[i][0],dp[i−1][1]+a[i])
d p [ i ] [ 1 ] = m a x ( d p [ i − 1 ] [ 1 ] , d p [ i ] [ 1 ] ) dp[i][1]=max(dp[i-1][1],dp[i][1]) dp[i][1]=max(dp[i−1][1],dp[i][1])
d p [ i ] [ 1 ] = m a x ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 0 ] − a [ i ] ) dp[i][1]=max(dp[i-1][1],dp[i-1][0]-a[i]) dp[i][1]=max(dp[i−1][1],dp[i−1][0]−a[i])
其中,因为dp[i][1]全为0,因此第三种可以省略。

long long a[300010];
long long dp[300010][2]; //dp[i][1]表示前i个数以减号结尾的最大值,dp[i][0]表示前i个数以加号结尾的最大值
int main()
{
    long long t;
    scanf("%lld", &t);
    while (t--)
    {
        fill(dp[0], dp[0] + 300010 * 2, 0);
        long long n, q;
        scanf("%lld%lld", &n, &q);
        for (long long i = 1; i <= n; i++)
        {
            scanf("%lld", &a[i]);
            dp[i][0] = max(dp[i - 1][0], a[i]);
        }
        for (long long i = 1; i <= n; i++)
        {
            dp[i][0] = max(dp[i - 1][1] + a[i], max(dp[i - 1][0], dp[i][0]));
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - a[i]);
        }
        printf("%lld\n", dp[n][0]);
    }
    return 0;
}