绿蓝黄牌ldx给我爆个系数
查看原帖
绿蓝黄牌ldx给我爆个系数
326254
LonginusMonkey楼主2024/8/11 15:28

我模拟退火WA3,系数是石

#include<bits/stdc++.h>
#define inf 1e18
#define int long long
//#define debug
using namespace std;
const int maxn = 100100, maxm = 22;

int ans=inf, arr[maxn], now[maxm], peo[maxm];

int n, m;

int work() {
	int tempans = 0;
	int tot = 1;
	for(int i=1; i<=m; ++i) {
		for(int j=1; j<=peo[now[i]]; ++j) {
			if(now[i] != arr[tot]) {
				tempans++;
			}
			tot++;
		}
	}
	#ifdef debug
	if(tempans == 6) {
		cout << "people:";
		for(int i=1; i<=m; ++i) {
			cout << peo[i] << " ";
		}
		cout << endl;
		cout << "now:";
		for(int i=1; i<=m; ++i) {
			cout << now[i] << " ";
		}
		cout << endl;
	}
	#endif
	ans = min(ans, tempans);
	return tempans;
}

double Rand() {
	return 1.0 * rand() / (RAND_MAX);
}

void simulate_anneal() {
	//int x = rand() % m + 1, y = rand() % m + 1;
	//swap(x, y)
	int last = work();
	for(double t=1e4; t>=1e-4; t*=0.99) {
		int a = rand() % m + 1, b = rand() % m + 1;
		if(a != b) {
			swap(now[a], now[b]);
		}
		double dt = work() - last;
		if(exp(-dt / t) > Rand()) {
			last = work();
			continue;
		} else {
			swap(now[a], now[b]);
		}
	}
}

signed main() {
	ios::sync_with_stdio(0); cin.tie(0);
	
	cin >> n >> m;
	for(int i=1; i<=n; ++i) {
		cin >> arr[i]; peo[arr[i]] ++;
	}
	
	for(int i=1; i<=m; ++i) {
		now[i] = i;
	}
	
	simulate_anneal();
	
	cout << ans;
	
	return 0;
}
2024/8/11 15:28
加载中...