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)

#include <bits/stdc++.h>
#define rep(i, n) for (rint i = 1; i <= (n); i ++)
#define re0(i, n) for (rint i = 0; i < (int) n; i ++)
#define travel(i, u) for (rint i = head[u]; i; i = e[i].nxt)
#define rint register int
using namespace std;

typedef long long lo;

template<typename tp> inline void read(tp &x) {
    x = 0; char c = getchar(); int f = 0;
    for (; c < '0' || c > '9'; f |= c == '-', c = getchar());
    for (; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
    if (f) x = -x;
}

#define pb push_back
#define p pair <int, int>
const int N = 6666;
int n, ans = 1e9;
vector <p> a, b;
char s[N], t[N];

inline void doit() {
    for (int add0 = 0; add0 <= 2 * n + 1; add0++) {
        // if ((add0 + (a.front() == b.front())) % 2 == 0)
        //     continue;
        vector <p> na;
        if (add0 <= n) {
            na = vector <p> (add0, p(0, 1));
            for (p v : a) na.pb(v);
        } else {
            na = vector <p> (add0 - n - 1, p(0, 1));
            for (p v : a) na.pb(v);
        }
        int i = 0, j = 0;
        bool valid = true;
        int now = 0;
        while (!(i == na.size() && j == b.size())) {
            if (i == na.size()) now += n + 1 - b[j++].second;
            else if (j == b.size()) now += n + 1 - na[i++].second;
            else {
                valid &= !na[i].first || na[i].first == b[j].first;
                now += abs(na[i++].second - b[j++].second);
            }
        }
        if (valid) {
            // cout << add0 << " " << now << "\n";
            ans = min(ans, now);
        }
    }
}

int main(void) {
    read(n);
    scanf("%s%s", s + 1, t + 1);
    re0 (i, n) {
        if (s[i + 1] != s[i]) a.pb(p(s[i + 1], i + 1));
        if (t[i + 1] != t[i]) b.pb(p(t[i + 1], i + 1));
    }
    // for (p v : a) cout << v.first << " "; cout << "\n";
    // for (p v : b) cout << v.first << " "; cout << "\n";
    doit();
    swap(a, b);
    doit();
    cout << ans << "\n";
}