比赛 2024国庆练习3 评测结果 AAAAAATTTTTTTTTTTTTT
题目名称 信号传递 最终得分 30
用户昵称 健康铀 运行时间 43.286 s
代码语言 C++ 内存使用 3.86 MiB
提交时间 2024-10-06 17:39:51
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
const int M = 25;
const double TMAX = 1e7;
const double D = 0.9999;
const double eps = 10.0;
int n, m, k, a[N], c[M], R[M][M];
int res = 0, ans = 1e9;
int dis(int x,int y)
{
	if(x<y)
		return y-x;
	return (x+y)*k;
}
void del(int x) {
	for (int i = 1; i <= m; ++i)
		if (i != x) {
			res -= R[x][i] * dis(c[x], c[i]);
			res -= R[i][x] * dis(c[i], c[x]);
		}
}
void add(int x) {
	for (int i = 1; i <= m; ++i)
		if (i != x) {
			res += R[x][i] * dis(c[x], c[i]);
			res += R[i][x] * dis(c[i], c[x]);
		}
}
void add(int x, int y) {
	res += R[x][y] * dis(c[x], c[y]);
	res += R[y][x] * dis(c[y], c[x]);
}
void del(int x, int y) {
	res -= R[x][y] * dis(c[x], c[y]);
	res -= R[y][x] * dis(c[y], c[x]);
}
void calc() {
	res = 0;
	for (int i = 1; i <= m; i++)
		for (int j = 1; j <= m; j++) {
			if (i == j) continue;
			res += R[i][j] * dis(c[i], c[j]);
		}
	ans = min(ans, res);
}
void SA() {
	calc();
	double T = TMAX;
	while (T > eps) {
		int x = rand() % m + 1, y = rand() % m + 1;
		while (x == y)
			x = rand() % m + 1, y = rand() % m + 1;
		int tans = res;
		del(x), del(y), add(x, y);
		swap(c[x], c[y]);
		add(x), add(y), del(x, y);
		int delta = res - tans;
		if (delta < 0)
			ans = min(ans, res);
		else if (exp(-delta / T)*RAND_MAX <= rand())
			res = tans, swap(c[x], c[y]);
		T *= D;
	}
}
int main() {
	freopen("haoi2020_transfer.in","r",stdin);
	freopen("haoi2020_transfer.out","w",stdout);
	cin >> n >> m >> k;
	if(n==1)
	{
		cout<<"0";
		return 0;
	}
	for (int i = 1; i <= n; ++i)
		cin >> a[i];
	for (int i = 1; i < n; ++i)
		R[a[i]][a[i + 1]]++;
	for (int i = 1; i <= m; i++)
		c[i] = i;
	srand(time(0));
	for (int i = 1; i <= 50; ++i)
		SA();
	cout << ans;
	return 0;
}