Processing math: 100%
(Analysis by Benjamin Qi)

Based off Modern Art 2, although the solution is completely different.

Subtask 2:

We can split the painting into groups of M=12 and run O(2Mpoly(M)) BFS on each group independently. A state consists of a bitmask of length M where the i-th bit of the bitmask is equal to one if the i-th cell is colored the way that it should be in the final painting, as well as the minimum number of strokes required to reach that bitmask (denoted by dist in the solution below).

To transition from a state, we go through each of the O(M2) possible ranges that a stroke can paint over and through each of the O(M) possible colors for the stroke.

Code (courtesy of Andrew Wang):

#include <bits/stdc++.h>
using namespace std;

const int MAX = 1e9;
vector<int> dist;
queue<int> q;

void add(int mask, int distance) { //add new mask to the queue + update distance
	if(dist[mask] != MAX)
		return;
	dist[mask] = distance;
	q.push(mask);
}

int solve(vector<int> v, int lowest_color) {
	int N = v.size();
	dist.assign(1<<N, MAX);
	add(0, 0);
	while (q.size()) {
		int x = q.front(); q.pop();
		for(int color = lowest_color; color < lowest_color+12; color++) {
			//loop through intervals with same beginning + ending color
			for(int i = 0; i < N; i++) {
				if(v[i] == color) {
					for(int j = i; j < N; j++) {
						if(v[j] == color) {
							int cur_mask = x; 
							for(int k = i; k <= j; k++) {
								//if same color, then update the mask as correctly painted
								if (v[k] == color) 
									cur_mask |= 1 << k;
								//if already painted correctly, update it as painted over incorrectly
								else if (cur_mask & (1<<k)) 
									cur_mask ^= 1 << k;
							}
							add(cur_mask, dist[x]+1);
						}
					}
				}
			}
		}
	}
	return dist[(1<<N)-1];
}

int main() {
	cin.tie(0)->sync_with_stdio(0); 
	int N; cin >> N;
	vector<int> cur_batch;
	int ans = 0;
	for(int i = 0; 12*i < N; i++) { //breaking it up in batches of size <= 12
		for(int j = 12*i; j < 12*(i+1) && j < N; j++) {
			int a; cin >> a;
			cur_batch.push_back(a);
		}
		ans += solve(cur_batch, 12*i+1);
		cur_batch.clear();
	}
	cout << ans << endl;
}

Full Solution:

Given an optimal way to paint, draw a segment between two distinct cells if they were last painted by the same stroke x and none of the cells in between them were last painted by stroke x. The number of strokes required is equal to N minus the number of such segments. For example, we can draw at most five segments for the following test case,

11
1 2 3 4 1 4 3 2 1 1 6

so the number of strokes required is 115=6.

        1
      4---4
    3-------3
  2-----------2
1---------------1-1 6

So we've reduced the problem to computing the maximum size of a set of segments satisfying all three of the following properties:

It suffices to do dynamic programming on ranges to compute the maximum possible number of segments. Define dp[i][j] to be the maximum possible number of segments if we only consider the range from cell i to cell j (0i<j<N).

Time Complexity: O(N3)

My code follows:

#include <bits/stdc++.h>
using namespace std;
 
int N, dp[305][305];
 
int main() {
	cin >> N;
	vector<int> a(N); 
	for (int& t: a) cin >> t;
	for (int i = N-1; i >= 0; --i) 
		for (int j = i+1; j < N; ++j) {
			if (a[i] == a[j]) // draw segment from i to j
				dp[i][j] = max(dp[i][j],1+dp[i+1][j-1]);
			for (int k = i+1; k < j; ++k) // split at k
				dp[i][j] = max(dp[i][j],dp[i][k]+dp[k][j]);
		}
	cout << N-dp[0][N-1] << "\n";
}