题意分析

这道题正解好像是折半状压 但是俺就是喜欢模拟退火

每一次随机的话 就是交换两个数的位置 然后比较前一半和后一半

CODE:

#include<bits/stdc++.h>
#define INF 0x7fffffff
#define N 2010
using namespace std;
int T,n;
long long ans;
long long num[N];
long long getans()
{
	long long sum1=0,sum2=0;
	int mid=(1+n)>>1;
	for(int i=1;i<=mid;++i) sum1+=num[i];
	for(int i=mid+1;i<=n;++i) sum2+=num[i];
	return abs(sum1-sum2);
}
void SA()
{
	for(double Te=3872;Te>1e-10;Te*=0.972)
	{
		int x=rand()%n+1,y=rand()%n+1;
		swap(num[x],num[y]);
		long long tmp=getans();
		if(tmp<ans) ans=tmp;
		else if(exp((double)(ans-tmp)/Te)*RAND_MAX<(double)rand()) swap(num[x],num[y]); 
	}
}
int main()
{
	srand(19260817+998244353);
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;++i) scanf("%lld",&num[i]);
		ans=INF;
		for(int x=1;x<=1000;++x) SA();
		printf("%lld\n",ans);
	}
	return 0;
}

相关文章:

  • 2021-07-24
  • 2022-03-08
  • 2021-12-02
  • 2021-07-06
  • 2022-12-23
  • 2022-12-23
  • 2021-08-14
  • 2021-09-03
猜你喜欢
  • 2021-08-19
  • 2022-12-23
  • 2021-09-28
  • 2022-02-15
  • 2021-06-21
  • 2021-09-06
相关资源
相似解决方案