Table of Contents

ExplanationImplementation

Official Analysis (C++)

This solution is O(N2)\mathcal{O}(N^2) which is faster than the official editorial's but not required since N100N \leq 100.

Explanation

Let dp[i][j]\texttt{dp}[i][j] be the the minimum number of changes that must be made to the first jj entries so that there are ii breakouts among the first jj entries.

There are three cases when we calculate the current value of dp[i][j]\texttt{dp}[i][j]:

  • If the log was tampered with and the cows would NOT breakout:

    • Compared to the previous day, the breakout number won't change. However, we need one more change of the log, so we transfer from dp[i][j1]\texttt{dp}[i][j-1].
      dp[i][j]=dp[i][j1]+1\texttt{dp}[i][j]=\texttt{dp}[i][j-1]+1
  • If the log was tampered with and the cows would breakout (Notice that a[j]0a[j] \neq 0):

    • Compared to the previous day the breakout number increases by 1. We also need one more change of the log, so we transfer from dp[i1][j1]\texttt{dp}[i-1][j-1].
      dp[i][j]=dp[i1][j1]+1\texttt{dp}[i][j]=\texttt{dp}[i-1][j-1]+1
  • If the log was NOT tampered with:

    • Then the ii-th breakout would be on the (ja[j])(j-a[j])-th day, so we transfer from dp[i1][ja[j]1]\texttt{dp}[i-1][j-a[j]-1].
      dp[i][j]=dp[i1][ja[j]1]+range_ans[ja[j]][j]);\texttt{dp}[i][j] = \texttt{dp}[i-1][j-a[j]-1]+\texttt{range\_ans}[j-a[j]][j]);

range_ans[l][r]\texttt{range\_ans}[l][r] represents the minimum cost to replace the range a[l]...a[r]a[l]...a[r] with 0...(rl)0...(r-l).

Thus, our final DP relation is

dp[i][j]=min{dp[i][j1]+1dp[i1][j1]+1dp[i1][ja[j]1]+range_ans[ja[j]][j])\texttt{dp}[i][j] = \min\begin{cases} \texttt{dp}[i][j-1]+1\\ \texttt{dp}[i-1][j-1]+1\\ \texttt{dp}[i-1][j-a[j]-1] + \texttt{range\_ans}[j-a[j]][j]) \end{cases}

Note that if the indices are out of bounds, the value is not considered.

Implementation

Time Complexity: O(N2)\mathcal{O}(N^2)

C++

#include <bits/stdc++.h>
using namespace std;
int main() {
freopen("taming.in", "r", stdin);
freopen("taming.out", "w", stdout);
int n;
cin >> n;
vector<int> entry(n);

Python

with open("taming.in", "r") as read:
n = int(read.readline().strip())
entry = list(map(int, read.readline().strip().split()))
range_ans = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(i, n):
if j > 0:
range_ans[i][j] = range_ans[i][j - 1] + (0 if entry[j] == j - i else 1)
else:

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!