0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AtCoder ABC182 D Wandering 解

Posted at

問題

考察

当然ながら愚直な全探索は $O(N^2)$ かかるので不可能。

任意回操作後のロボの位置は、事前にA[]の累積和cs[]を計算しておくことで、dp によって$O(N)$で計算できる。だから、(i-1)回目の操作終了後の位置を所与として、次の i 回目の合計 i 個の操作 $(+A_1,...,+A_i)$ を行う過程における位置 $p_i$ の最大値を高速に(遅くとも$O(\log N)$ で) 計算できれば良い。

この $p_i$ は、(i-1)回目の操作終了後の位置 $dp_{i-1}$ に、i 回目の操作における移動の最大幅を足すことで求められる。後者は、i 個の移動$(+A_1,...,+A_i)$ を順に行っていく際の累積和の最大値だから、$p_i = dp_{i-1}+\min_{k \le i} cs_k$ と計算できる。この右辺第二項(pmax[i]と呼ぶことにする)は、明らかに位置情報dp[]とは無関係に、累積和cs[]に対する漸化式として動的に$O(N)$で計算できる。

cs[]pmax[]を事前に計算しておくことにより、全体の計算量は$O(N)$に収まる。

実装

以上の考察を素直に実装するだけ。

int main() {
    // read input
    auto n = in<ll>();
    auto a = vin<ll>(n);

    // cumulative sum
    vector<ll> cs(n, 0);
    cs[0]              = a[0];
    rep(i, 1, n) cs[i] = cs[i - 1] + a[i];

    // path max
    vector<ll> pmax(n, 0);
    pmax[0]              = max(0, a[0]);
    rep(i, 1, n) pmax[i] = max(pmax[i - 1], cs[i]);

    // calc by dp
    ll ans = max(0, a[0]);
    vector<ll> dp(n, 0);
    dp[0] = a[0];
    rep(i, 1, n) {
        chmax(ans, dp[i - 1] + pmax[i]);
        dp[i] = dp[i - 1] + cs[i];
    }
    // show
    print(ans);
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?