Problem:
Score : 1400 points

Problem Statement

You are given strings s and t, both of length N.
s and t consist of 0 and 1. Additionally, in these strings, the same character never occurs three or more times in a row.

You can modify s by repeatedly performing the following operation:

Choose an index i (1 \leq i \leq N) freely and invert the i-th character in s (that is, replace 0 with 1, and 1 with 0), under the condition that the same character would not occur three or more times in a row in s after the operation.

Your objective is to make s equal to t.
Find the minimum number of operations required.

Constraints

1 \leq N \leq 5000

The lengths of s and t are both N.

s and t consists of 0 and 1.

In s and t, the same character never occurs three or more times in a row.

Input

Input is given from Standard Input in the following format:

N
s
t

Output

Find the minimum number of operations required to make s equal to t. It can be proved that the objective is always achievable in a finite number of operations.

Sample Input 1

4
0011
0101

Sample Output 1

4

One possible solution is 0011 → 1011 → 1001 → 1101 → 0101.

Sample Input 2

1
0
0

Sample Output 2

0

Sample Input 3

8
00110011
10101010

Sample Output 3

10

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

// I need some holiday
// But I don't wish that everyday is holiday
// Because I didn't bear the pain
// Because it wasn't a true freedom
//         ——『イヤホンと蝉時雨』·Orangestar

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef unsigned int UI;
typedef pair<int, int> pii;

#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define MP make_pair
#define fst first
#define snd second
#define SZ(u) ((int) (u).size())
#define ALL(u) (u).begin(), (u).end()

inline void proc_status()
{
	ifstream t("/proc/self/status");
	cerr << string(istreambuf_iterator<char>(t), istreambuf_iterator<char>()) << endl;
}

template<typename T> inline int chkmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline int chkmax(T &a, const T &b) { return b > a ? a = b, 1 : 0; }
template<typename T> inline T sqr(const T &val) { return val * val; }

namespace fastIO
{
	const int MAX_BUFFER_SIZE = 1 << 16;

	char buffer[MAX_BUFFER_SIZE], *cur = buffer, *ed = buffer;

	inline char getc() { return cur == ed && (ed = (cur = buffer) + fread(buffer, 1, MAX_BUFFER_SIZE, stdin), cur == ed) ? EOF : *cur++; }
}
using fastIO::getc;

template<typename T> inline T read()
{
	register T sum(0), fg(1);
	register char ch(getc());
	for(; !isdigit(ch); ch = getc()) if(ch == '-') fg = -1;
	for(;  isdigit(ch); ch = getc()) sum = sum * 10 - '0' + ch;
	return sum * fg;
}

inline char *read_str(char *s)
{
	register char ch(getc());
	while(!isgraph(ch)) ch = getc();
	for(; isgraph(ch); ch = getc()) *s++ = ch;
	*s = '\0';
	return s;
}

// END tpl.

const int MAXN = (int) 5e3;

int n;

char s[MAXN + 5], t[MAXN + 5];

inline void input()
{
	n = read<int>();
	read_str(s + 1);
	read_str(t + 1);
}

inline void solve()
{
	if(n <= 2)
	{
		int ans = 0;
		for(int i = 1; i <= n; ++i) ans += s[i] != t[i];
		printf("%d\n", ans);
		return;
	}

	static int a[MAXN + 5], b[MAXN + 5];

	int cnta[2] = {0, 0}, cntb[2] = {0, 0};
	for(int i = 1; i < n; ++i)
	{
		if(s[i] != s[i + 1]) ++cnta[a[i] = s[i] == '0' ? 0 : 1]; else a[i] = -1;
		if(t[i] != t[i + 1]) ++cntb[b[i] = t[i] == '0' ? 0 : 1]; else b[i] = -1;
	}

	auto calc = [cnta, cntb] (int d)
	{
		static vector<int> A, B;
		A.clear();
		B.clear();

		for(int i = 1; i < n; ++i) if(a[i] == d) A.push_back(i);

		for(int i = 1; i <= n; ++i) B.push_back(0);
		for(int i = 1; i < n; ++i) if(b[i] == d) B.push_back(i);
		for(int i = 1; i <= n; ++i) B.push_back(n);

		int ans = INT_MAX;
		for(int i = 0; i + SZ(A) < SZ(B); ++i)
		{
			int res = 0;
			for(int j = 0; j < i; ++j) res += B[j];
			for(int j = 0; j < SZ(A); ++j) res += abs(A[j] - B[i + j]);
			for(int j = i + SZ(A); j < SZ(B); ++j) res += abs(n - B[j]);
			chkmin(ans, res);
		}
		return ans;
	};

	printf("%d\n", calc(0) + calc(1));
}

int main()
{
#ifdef K_ON
	freopen("E.in", "r", stdin);
	freopen("E.out", "w", stdout);
#endif

	input();
	solve();

	return 0;
}