Processing math: 100%
(Analysis by Dhruv Rohatgi )

This problem can be solved by dynamic programming. Let dp(i,j,k) be the minimum number of changes that must be made to the first i entries so that there are k breakouts among the first i entries, and the last of these k breakouts occurs at index j.

Suppose we want to compute dp(i,j,k) for some fixed i,j, and k. Then entry i must be equal to ij; if not, we have to change entry i. Now we simply need to count the minimum number of changes that need to be made to the first i1 entries. There are two cases: either j<i or j=i.

If j<i, then the most recent breakout out of the first i1 days must have been on day j. So the quantity we want is dp(i1,j,k).

If j=i, then the most recent breakout out of the first i1 days could have been on any day. So the quantity we want is minj<idp(i1,j,k1).

There are O(N3) dynamic programming states. The first transition takes O(1) time. The second transition takes O(N) time, but only occurs in O(N2) states. Therefore the overall time complexity is O(N3).

#include <iostream>
#include <algorithm>
using namespace std;
#define INF 1000

int N;
int A[100];
int dp[100][100][101];	//[current index][last breakout][number of breakouts]

int main()
{
	cin >> N;
	for(int i=0;i<N;i++)
		cin >> A[i];
	for(int i=0;i<N;i++)
		for(int j=0;j<=i;j++)
			for(int k=0;k<=N;k++)
				dp[i][j][k] = INF;
	if(A[0] == 0)
		dp[0][0][1] = 0;
	else
		dp[0][0][1] = 1;
	for(int i=1;i<N;i++)
	{
		for(int j=0;j<=i;j++)
			for(int k=1;k<=i+1;k++)
			{
				if(j < i) 
					dp[i][j][k] = dp[i-1][j][k];
				else
					for(int j1=0;j1<i;j1++)
						dp[i][j][k] = min(dp[i][j][k], dp[i-1][j1][k-1]);
				if(A[i] != i-j) 
					dp[i][j][k]++;
			}
	}
	for(int k=1;k<=N;k++)
	{
		int low = INF;
		for(int j=0;j<N;j++)
			low = min(low, dp[N-1][j][k]);
		cout << low << '\n';
	}
}