Toy と帽子と ADP BE

主にプログラミングに関わる話をゆるくエモくやっていきます

B. Maximums (Codeforces Global Round 7)

問題

https://codeforces.com/contest/1326/problem/B

問題概要

非負整数からなる数列a=\{a_1,a_2,...a_n\}がある。また、1からnまでのそれぞれについてx_imax(0,a_1,...,a_{i-1})と定義する。ここでi=1のときx_i=0であることに注意する。

例えばa=\{0, 1, 2, 0, 3\}のときx=\{0, 0, 1, 2, 2\}である。

ここで任意のiについてb_ia_i-x_iと定義する。

例えば上記の配列axに対してb\{0-0, 1-0, 2-1, 0-2, 3-2\}でありb=\{0, 1, 1, -1, 1\}となる。

さて、配列bが与えられるので、配列aを復元せよ。

考察

b_i=a_i-x_iなので移項してa_i=b_i+x_iです。ここでx_1=0であることはわかっているので、実はa_1=b_1です。まずa_1がわかりました。

x_2=max(0, a_1)ですので、a_1がわかるとx_2もわかります。するとa_2=b_2+x_2なのでa_2がわかります。

というように、この問題は端から順に単純な計算で解決できるのでした。

実装上の工夫として計算したmaxを保存しておくとよいでしょう。

#include <bits/stdc++.h>
using namespace std;
 
int main() {
    int n;
    cin >> n;
    vector<int> a(n);
    vector<int> b(n);
    for (int i = 0; i < n; i++) cin >> b[i];
    a[0] = b[0];
    a[1] = b[0] + b[1];
    int mx = max(a[0], a[1]);
    for (int i = 2; i < n; i++) {
        a[i] = mx + b[i];
        mx = max(mx, a[i]);
    }
    for (int i = 0; i < n; i++) {
        cout << a[i] << (i == n - 1 ? '\n' : ' ');
    }
}

反省

max(a[0], a[1])と書いていたつもりが、(a[0], a[1])と書いていたことに気づかず2WA・・・。なんともったいない。でもこれでもpretest 7まで行ってしまうのはどうかと思う・・・。こどふぉのpretest本当にあてにならないです。