Codeforces#407C. Functions again(DP)

C. Functions again
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Something happened in Uzhlyandia again... There are riots on the streets... Famous Uzhlyandian superheroes Shean the Sheep and Stas the Giraffe were called in order to save the situation. Upon the arriving, they found that citizens are worried about maximum values of the Main Uzhlyandian Function f, which is defined as follows:

In the above formula, 1 ≤ l < r ≤ n must hold, where n is the size of the Main Uzhlyandian Array a, and |x| means absolute value of x. But the heroes skipped their math lessons in school, so they asked you for help. Help them calculate the maximum value of f among all possible values of l and r for the given array a.

Input

The first line contains single integer n (2 ≤ n ≤ 105) — the size of the array a.

The second line contains n integers a1, a2, ..., an (-109 ≤ ai ≤ 109) — the array elements.

Output

Print the only integer — the maximum value of f.

Examples
input
5
1 4 2 3 1
output
3
input
4
1 5 4 7
output
6
Note

In the first sample case, the optimal value of f is reached on intervals [1, 2] and [2, 5].

In the second case maximal value of f is reachable only on the whole array.


本来是一题挺简单的水题,用笔算了下很快发现这是跟max sum有关的。但被一个坑点WA了两次。

例如例题

5

1 4 2 3 1

1和4的绝对值是3,4和2的绝对值是2,。。。。

b[i]=abs(a[i]-a[i+1])*flag

flag是用来判断正负号的

很快得到3 -2 1 -2

从这里能发现找到l到r的最大子串就是和求max sum一样。发现问题后我很快写下代码。

不会求最大子串和的看下这个http://blog.csdn.net/code_pang/article/details/7772200

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int a[100005],b[100005];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    int flag=1;
    for(int i=0;i<n-1;i++)
    {
        b[i]=abs(a[i]-a[i+1])*flag;
        flag*=-1;
    }
    int maxn=0,temp=0;
    for(int i=0;i<n-1;i++)
    {
        temp+=b[i];
        if(temp>maxn)
            maxn=temp;
        else if(temp<0)
            temp=0;
    }
    printf("%d\n",maxn);
    return 0;
}


但我WA了,但是怎么想都不对,后来发现f(l,r)的第一个因为(-1)^i-l,而i是从l开始的,所以每个开头都是正的。如果l是偶数则偶数都是正数,奇数都是负数,而如果l是奇数则奇数的都是正数,偶数的都为负数,也就是说每个b[i]都有正或负的时候。

所以就是有两个总串。

例如第一个例子

5

1 4 2 3 1

第一个总串是3 -2 1 -2

第二个总串是-3 2 -1 2

那么那个最大的子串和就在这两个总串之中

所以代码如下

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
#define ll long long
int a[100005],b[100005],c[100005];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    int flag=1;
    for(int i=0;i<n-1;i++)
    {
        b[i]=abs(a[i]-a[i+1])*flag;
        c[i]=-b[i];
        flag*=-1;
    }
    ll maxn=0,temp=0;
    for(int i=0;i<n-1;i++)
    {
        temp+=b[i];
        if(temp>maxn)
            maxn=temp;
        else if(temp<0)
            temp=0;
    }
    ll maxn1=0;
    temp=0;
    for(int i=0;i<n-1;i++)
    {
        temp+=c[i];
        if(temp>maxn1)
            maxn1=temp;
        else if(temp<0)
            temp=0;
    }
    printf("%lld\n",max(maxn1,maxn));
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值