[Codeforces] Educational Codeforces Round 95 (Div. 2) C. Mortal Kombat Tower
問題
方針
友人の行動は、ボスを倒すまたはボスをスキップすることができます。また、自分と友人は最低でも \( 1 \) 体のボスに対応しなければならなく、\( 1 \) 回のセッションで最大で \( 2 \) 体のボスを倒すことができます。
ここで友人が \( i \) 番目のボスを同一セッションで \( 1 \) 体目のボスであるときのスキップした回数を \( f(i, 0) \) とし、同一セッションで \( 2 \) 体目のボスであるときのスキップした回数を \( f(i, 1) \) とします。同様に \( g(i, 0), g(i, 1) \) を定義します。
初期値は、\( f(1, 0) = a_1\) となり、その他は \( \infty \) で初期化します。更新式は、
\begin{eqnarray}
f(i + 1, 0) &=& \min(g(i, 0), g(i, 1)) + a_{i+1}\\
f(i + 1, 1) &=& f(i, 0)+ a_{i+1}\\
g(i + 1, 0) &=& \min(f(i, 0), f(i, 1))\\
g(i + 1, 1) &=& g(i, 0)
\end{eqnarray}
となります。
コード
#include <bits/stdc++.h> using namespace std; typedef long long ll; int a[200000]; int solve(int n) { int f[n][2]; int g[n][2]; for(int i = 0; i < n; i++) { for (int j = 0; j < 2; j++) { g[i][j] = n; f[i][j] = n; } } if (a[0]) { f[0][0] = 1; } else { f[0][0] = 0; } for (int i = 0; i < n - 1; i++) { f[i + 1][0] = min(g[i][0], g[i][1]) + a[i + 1]; f[i + 1][1] = f[i][0] + a[i + 1]; g[i + 1][0] = min(f[i][0], f[i][1]); g[i + 1][1] = g[i][0]; } int best = n; for (int i = 0; i < 2; i++) { best = min(best, f[n - 1][i]); best = min(best, g[n - 1][i]); } return best; } int main() { int t, n; cin >> t; int ans[t]; for (int i = 0; i < t; i++) { cin >> n; for (int j = 0; j < n; j++) { cin >> a[j]; } if (n == 1) { ans[i] = a[0]; } else { ans[i] = solve(n); } } for (int i = 0; i < t; i++) { cout << ans[i] << "\n"; } return 0; }
ディスカッション
コメント一覧
まだ、コメントがありません