1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| const int N = 1e3 + 10; int n, a[N], p[N]; LL val, score[11]; std::mt19937 rnd;
inline int pre(int x) { return (x + n - 2) % n + 1; } inline int nxt(int x) { return x % n + 1; }
LL getval(int i) { return (LL) p[i] * a[p[i]] * a[p[pre(i)]] * a[p[nxt(i)]]; }
LL calc(int l, int r) { LL res = 0; for (int i = l; i <= r; ++ i) res += getval(i); return res; }
void SA() { int x = rnd() % n + 1, y = rnd() % n + 1; if (x == y) return; LL nw = val; std::vector<int> v{pre(x), x, nxt(x)}; if (std::find(v.begin(), v.end(), pre(y)) == v.end()) v.push_back(pre(y)); if (std::find(v.begin(), v.end(), y) == v.end()) v.push_back(y); if (std::find(v.begin(), v.end(), nxt(y)) == v.end()) v.push_back(nxt(y)); for (int x : v) nw -= getval(x); std::swap(p[x], p[y]); for (int x : v) nw += getval(x); if (nw < val) std::swap(p[x], p[y]); else val = nw; }
struct Timer { ~Timer() { std::cout << clock() / 1000000. << " s used" << std::endl; } } timer;
int main(int argc, char *argv[]) { std::ifstream fin(argv[1]), fans(argv[2]); fin >> n; rnd.seed((long long) new char); for (int i = 1; i <= n; ++ i) fin >> a[i]; std::vector<int> curp{1, 2, 3}; for (int i = 4; i <= n; ++ i) { for (int j = 0; j < i - 1; ++ j) if (curp[j] == i - 2 || curp[j] == i - 1) { curp.insert(curp.begin() + j + 1, i); break; } } for (int i = 0; i < n; ++ i) p[i + 1] = curp[i]; for (int i = 0; i < 10; ++ i) fans >> score[i]; fin.close(), fans.close(); LL cnt = 0; val = calc(1, n); while (++ cnt) { SA(); if (cnt % 1000000 == 0) { int curscore = 0; for (int i = 0; i < 10; ++ i) curscore += val >= score[i]; if (cnt % 2000000 == 0) { printf("SA cnt : %lld Val : %lld Score : %d Goal val : %lld Delta : %.10lf\n", cnt, val, curscore, score[9], (val - score[9]) * 1. / score[9]); std::ofstream fout("test.out"); for (int i = 1; i <= n; ++ i) fout << p[i] << ' '; fout.close(); } if (cnt % 6000000 == 0) { int T = 25; while (T --) std::swap(p[rnd() % n + 1], p[rnd() % n + 1]); val = calc(1, n); } } } return 0; }
|