E - Addition and Subtraction Hard AtCoder - 2273 思维观察题

http://arc066.contest.atcoder.jp/tasks/arc066_c?lang=en

这类题目是我最怕的,没有什么算法,但是却很难想,

这题的题解是这样的,观察到,在+号里面添加括号是没用的,

那么看看减号,任意两个相邻减号,

比如1 - 20 + 8 - 13 - 5 + 6 + 7 - 8

可以变成1 - (20 + 8 - 13) + 5 + 6 + 7 + 8

为什么后面的可以全部都变成正数呢?

因为可以这样变,1 - (20 + 8 - 13 - (5 + 6 + 7) - 8)

所以,观察到,这个观察到,到底需要多大的脑洞呢?

暴力枚举任意一对相邻的减号,只有其里面包括的数字全部变成负数为代价,使得后面的数字全部变正。

暴力枚举即可。

#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 perfixSum[maxn], absSum[maxn];
vector<int>pos;
void cut(LL &val, int pos1, int pos2) {
    if (pos1 > pos2) return;
    val -= absSum[pos2] - absSum[pos1 - 1];
}
void work() {
    int n;
    scanf("%d", &n);
    int val;
    scanf("%d", &val);
    perfixSum[1] = val;
    absSum[1] = val;
    for (int i = 2; i <= n; ++i) {
        int val;
        char op;
        cin >> op;
        scanf("%d", &val);
        if (op == '+') {
            perfixSum[i] = perfixSum[i - 1] + val;
        } else {
            perfixSum[i] = perfixSum[i - 1] - val;
            pos.push_back(i);
        }
        absSum[i] = absSum[i - 1] + val;
    }
    LL ans = perfixSum[n];
    for (int i = 0; i <= (int)pos.size() - 2; ++i) {
        int p1 = pos[i], p2 = pos[i + 1];
        LL tans = absSum[n] - absSum[p2 - 1];
        tans += perfixSum[p1];
        cut(tans, p1 + 1, p2 - 1);
        ans = max(ans, tans);
    }
    cout << ans << endl;
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
//    int val;
//    scanf("%d", &val);
//    cout << val << endl;
    work();
    return 0;
}
View Code

 

posted on 2017-03-15 20:44  stupid_one  阅读(172)  评论(0编辑  收藏  举报

导航