C. Functions again DP + 分类讨论

http://codeforces.com/contest/789/problem/C

首先按题目要求处理出dis数组。

那么对于任意一个区间,[L, R],是dis[L] - dis[L + 1] + dis[L + 2] .... + 

那么怎么知道是+还是—呢?

注意到对于一个数,要么是正,要么是负。

考虑第一个数,是正的时候,第三个数肯定是取正,第二个数肯定只能是负。

那么就是对这个数组求一次最大字段和

同理第一个数是负数的情况。

 

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 1e5 + 20;
LL a[maxn], dis[maxn];
LL dp[maxn];
void work() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    LL ans = 0;
    for (int i = 1; i <= n - 1; ++i) {
        dis[i] = abs(a[i] - a[i + 1]);
    }
    for (int i = 1; i <= n - 1; i += 2) {
        dis[i] = -dis[i];
    }
    for (int i = 1; i <= n - 1; ++i) {
        dp[i] = max(dp[i - 1] + dis[i], dis[i]);
        ans = max(ans, dp[i]);
    }
    memset(dp, 0, sizeof dp);
    for (int i = 1; i <= n - 1; i += 2) {
        dis[i] = -dis[i];
    }
    for (int i = 2; i <= n - 1; i += 2) {
        dis[i] = -dis[i];
    }
    for (int i = 1; i <= n - 1; ++i) {
        dp[i] = max(dp[i - 1] + dis[i], dis[i]);
        ans = max(ans, dp[i]);
    }
    cout << ans << endl;
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}
View Code

 

posted on 2017-03-30 14:10  stupid_one  阅读(197)  评论(0编辑  收藏  举报

导航