EDPC N - Slimes

スライム

考え方

ABCでいうと、E問題級。

基本的にはただの区間 DP で、L 問題と同じように解けばよい。
ただし、「今回の合体コスト」を計算するときに長大な和を取る必要がある。
そのため、累積和のアルゴリズムを同時に用いる。

dp[l][r] を、l 番目から r 番目までのスライムを合体させる場合の最小コストとする。
最後に合体する境界を全パターン試すと、次の形になる。

dp[l][r] = min(dp[l][m-1] + dp[m][r]) + 区間全体の大きさ

区間全体の大きさは、累積和を使って求めればよい。

計算量は $O(N^3)$。

入力例1での動作

入力を受け取る。

n: 4
a: {10, 20, 30, 40}

まず、累積和を作る。

sum: {0, 10, 30, 60, 100}

dp[l][r] を、区間 a[l] から a[r] までのスライムを合体させる最小コストとする。

残り $1$ 匹の場合、合体する必要がないのでコストは $0$ である。

左端\右端 10 20 30 40
10 0 - - -
20 - 0 - -
30 - - 0 -
40 - - - 0

たとえば、dp[2][3] を考える。
この区間は a[2]a[3] だけなので、最後にその $2$ 匹を合体させるしかない。

dp[2][3] = dp[2][2] + dp[3][3] + (sum[4] - sum[2])
         = 0 + 0 + 70
         = 70

この提出コードでは、表の下段から順に、左から埋めていく。
具体的には、次の順に値が確定する。

dp[2][3]
dp[1][2] -> dp[1][3]
dp[0][1] -> dp[0][2] -> dp[0][3]

dp[0][3] では、最後に合体する境界を全て試す。

dp[0][3] = min(
  dp[0][0] + dp[1][3],
  dp[0][1] + dp[2][3],
  dp[0][2] + dp[3][3]
) + (sum[4] - sum[0])

それぞれの値を入れると、次のようになる。

dp[0][3] = min(0 + 140, 30 + 70, 90 + 0) + 100
         = min(140, 100, 90) + 100
         = 190

実際に埋めると、次のようになる。

左端\右端 10 20 30 40
10 0 30 90 190
20 - 0 50 140
30 - - 0 70
40 - - - 0

右上の $190$ が答えである。

注意点

答えは、int 型からはみ出る。
DP テーブルを含め、long long 型を用いること。

別解

特になし。