退火恒定WA#9 #10玄关求助
查看原帖
退火恒定WA#9 #10玄关求助
796838
Zak_chen楼主2023/10/19 18:04

rt

#include<bits/stdc++.h>
#define N 200005
#define eps 1e-15
#define down 0.99995
#define int long long
using namespace std;
int n,m,sum[N],tot[25][N];
int ans,answ;
vector<int>p;
int calc(vector<int> aa)
{
	int st=1,ed=0,ret=0;
	for(int i=0;i<aa.size();i++)
	{
		int col= aa[i];
		ed+=sum[col];
		ret += sum[col] - (tot[col][ed] - tot[col][st-1]);
		st+=sum[col];
	}
	return ret;
}
void SA()
{
	
	double T = 5000;
	while(T>eps)
	{
		if((double)clock()/CLOCKS_PER_SEC > 0.95) return;
		int pos1 = rand()%m;
		int pos2 = rand()%m;
		if(pos1==pos2) pos1 = rand()%m;
		swap(p[pos1],p[pos2]);
		int nw = calc(p);
		int del = nw-answ;
		double delta = (double)del*1.0;
		if(del < 0)
		{
			answ = nw; 
		}
		else if(exp(-delta*1.0 / T) *RAND_MAX <= rand())
		{
			swap(p[pos1],p[pos2]);
		} 
		T*=down; 
	}
}
signed main()
{
	srand((unsigned)time(NULL));
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		int tmp;cin>>tmp;
		sum[tmp]++;
		tot[tmp][i]++;
	}
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)	
		{
			tot[i][j] += tot[i][j-1];
//		printf("%d ",tot[i][j]);
		}
//		cout<<endl;
	}
	for(int i=1;i<=m;i++) p.push_back(i);
	random_shuffle(p.begin(),p.end());
//	for(int i=0;i<p.size();i++) printf("%d ",p[i]);
	answ = calc(p);
	while((double)clock()/CLOCKS_PER_SEC < 0.95) SA();
	cout<<answ<<endl;
	return 0;
}
2023/10/19 18:04
加载中...