#include using namespace std; #define m_p make_pair const int N = 402; int n; int a[N]; int ca[N]; int cc1, cc2; int c1[N][N], c2[N][N]; int cans[N]; vector > ans[N]; int t[N * 4]; void bil(int tl, int tr, int pos) { t[pos] = (tr - tl + 1); if (tl == tr) return; int m = (tl + tr) / 2; bil(tl, m, pos * 2); bil(m + 1, tr, pos * 2 + 1); } int qry(int tl, int tr, int pos) { t[pos]--; while (tl == tr) { return tl; } int m = (tl + tr) / 2; if (t[pos * 2] == 0) return qry(m + 1, tr, pos * 2 + 1); if (t[pos * 2 + 1] == 0) return qry(tl, m, pos * 2); if (rand() % 2) return qry(tl, m, pos * 2); qry(m + 1, tr, pos * 2 + 1); } //11111111111111111111111111111111111111111111 bool c[N]; int p[N]; void djk(int x) { for (int i = 1; i <= n; ++i) c[i] = false; priority_queue > > q; q.push(m_p(0, m_p(x, -1))); while (1) { pair > t = q.top(); do { t = q.top(); q.pop(); } while (c[t.second.first]); c[t.second.first] = true; p[t.second.first] = t.second.second; if (t.second.first == a[x]) return; for (int i = 1; i <= n; ++i) { if (a[i] == i) continue; pair > h = m_p(t.first + c1[t.second.first][i] + c2[a[x]][a[i]], m_p(i, t.second.first)); q.push(h); } } } int v[N]; void solv1() { for (int i = 1; i <= n; ++i) a[i] = ca[i]; for (int i = 1; i <= n; ++i) v[a[i]] = i; bil(1, n, 1); for (int ii = 1; ii <= n; ++ii) { int i = qry(1, n, 1); if (v[i] == i) continue; djk(v[i]); vector > yans; for (int j = i; j != v[i]; j = p[j]) yans.push_back(m_p(p[j], j)); reverse(yans.begin(), yans.end()); for (int j = 0; j < yans.size(); ++j) { cans[1] += (c1[yans[j].first][yans[j].second] + c2[a[yans[j].first]][a[yans[j].second]]); swap(a[yans[j].first], a[yans[j].second]); v[a[yans[j].first]] = yans[j].first; v[a[yans[j].second]] = yans[j].second; ans[1].push_back(yans[j]); } } } //22222222222222222222222222222222222222222222222 void solv2() { for (int ii = 0; ii < N; ++ii) { for (int i = 1; i <= n; ++i) a[i] = ca[i]; for (int i = 1; i <= n; ++i) v[a[i]] = i; bil(1, n, 1); for (int i = 1; i <= n; ++i) p[i] = qry(1, n, 1); int ycans = 0; vector > yans; for (int i = 1; i <= n; ++i) { int j = v[p[i]]; yans.push_back(m_p(p[i], j)); ycans += (c1[p[i]][j] + c2[a[p[i]]][a[j]]); swap(a[j], a[p[i]]); v[a[j]] = j; v[a[p[i]]] = p[i]; } if (ycans < cans[2] || ii == 0) { cans[2] = ycans; ans[2] = yans; } } } //333333333333333333333333333333333333333333333333333 void solv3() { for (int i = 1; i <= n; ++i) { for (int j = 1; j < n; ++j) { if (a[j] > a[j + 1]) { ans[3].push_back(m_p(j, j + 1)); cans[3] += (c1[j][j + 1] + c2[a[j]][a[j + 1]]); swap(a[j], a[j + 1]); } } } } //4444444444444444444444444444444444444444444444444444 void solv4() { for (int iii = 0; iii < n; ++iii) { int minu = 99999999, ii, jj; for (int i = 1; i <= n; ++i) { if (a[i] == i) continue; for (int j = 1; j <= n; ++j) { if (a[j] == i) { if (c1[j][i] + c2[a[j]][a[i]] < minu) { minu = c1[j][i] + c2[a[j]][a[i]]; ii = i; jj = j; break; } } } } cans[4] += minu; ans[4].push_back(m_p(ii, jj)); swap(a[ii], a[jj]); } } /////////////////////////////////////////////////////// int main() { //freopen("input.txt", "r", stdin); freopen("sorting.in", "r", stdin); freopen("sorting.out", "w", stdout); cin >> n; for (int i = 1; i <= n; ++i) { cin >> a[i]; } cin >> cc1; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { cin >> c1[i][j]; } } cin >> cc2; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { cin >> c2[i][j]; } } for (int i = 1; i <= n; ++i) ca[i] = a[i]; solv1(); for (int i = 1; i <= n; ++i) a[i] = ca[i]; solv2(); for (int i = 1; i <= n; ++i) a[i] = ca[i]; solv3(); for (int i = 1; i <= n; ++i) a[i] = ca[i]; solv4(); int minu = cans[1], mini = 1; for (int i = 2; i <= 4; ++i) { if (cans[i] < minu) { minu = cans[i]; mini = i; } } //cout << mini << endl; cout << ans[mini].size() << endl; for (int i = 0; i < ans[mini].size(); ++i) cout << ans[mini][i].first << ' ' << ans[mini][i].second << endl; return 0; }