Codeforces Round #318 (Div.1) B. Bear and Blocks

解法

1ステップ後の h[i] の高さは min(h[i - 1], h[i] - 1, h[i + 1]) になる。
一般化して、k ステップ後の h[i] の高さは min(h[i - k], h[i - k + 1] - 1, ..., h[i] - k, ..., h[i + k]) になる。
逆に考えると、h[i] の高さが 0 になるときは、ある j に対して min(h[i - j] - (k - j)) = 0 (j = -k, ..., k) が成り立つ時なので、k = h[i - j] + j である。
これは、左(と右)から順番に見ていけば求めることができるので、線形で解ける。

問題文

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n; cin >> n;
    vector<int> h(n + 2);
    for(int i = 1; i <= n; ++i) {
        cin >> h[i];
    }

    auto calc = [n] (vector<int> hs, bool rev = false) {
        if(rev) reverse(begin(hs), end(hs));
        vector<int> vs(n + 2);
        int mini = 0;
        for(int i = 1; i <= n; ++i) {
            mini++;
            if(mini > hs[i]) mini = hs[i];
            vs[i] = mini;
        }
        if(rev) reverse(begin(vs), end(vs));
        return vs;
    };
    auto left = calc(h), right = calc(h, true);

    int ans = 0;
    for(int i = 1; i <= n; ++i) {
        ans = max(ans, min(left[i], right[i]));
    }

    cout << ans << endl;
}

感想

なんで解けなかったのか、これがわからない。
完全に変なことを考えて泥沼化していた。