ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

模拟退火模板

2022-09-13 19:31:50  阅读:208  来源: 互联网

标签:__ typedef long 模拟退火 模板 pair gi define


考前必看!!1

[NOIP2021] 方差

#include <bits/stdc++.h>

#define DEBUG fprintf(stderr, "Passing [%s] line %d\n", __FUNCTION__, __LINE__)
#define File(x) freopen(x".in","r",stdin); freopen(x".out","w",stdout)
#define rep(i, x, y) for (int i = (x); i <= (y); i+=1)
#define epr(i, x) for (int i = head[x]; i; i = nxt[i])
#define per(i, x, y) for (int i = (x); i >= (y); i-=1)
#define DC int T = gi <int> (); while (T--)
#define Add(a, b) a = (a + b) % mod
#define chkmin(a, b) a = min(a, b)
#define chkmax(a, b) a = max(a, b)
#define pb push_back
#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int, int> PII;
typedef pair <LL, int> PLI;
typedef pair <int, LL> PIL;
typedef pair <LL, LL> PLL;

template <typename T>
inline T gi()
{
	T x = 0, f = 1; char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return f * x;
}

const int N = 10003, M = N << 1;
const double dlt = 0.9975, eps = 1e-14;

int n, a[N], b[N], cf[N];
LL ans = 1e18;

inline LL query()
{
	a[1] = 0;
	rep(i, 2, n) a[i] = a[i - 1] + cf[i];
	LL res = 0, tmp = 0;
	rep(i, 1, n) res += 1ll * a[i] * a[i], tmp += a[i];
	tmp = 1ll * tmp * tmp;
	res = 1ll * res * n - tmp;
	return res;
}

inline void SA()
{
	double T = 1000;
	while (T > eps)
	{
		if ((double)clock() / CLOCKS_PER_SEC > 0.993) {printf("%lld\n", ans); exit(0);}
		int x = rand() % (n - 2) + 3;
		swap(cf[x], cf[x - 1]);
		LL tans = query(), Dlt = tans - ans;
		if (Dlt < 0) ans = tans;
		else if (exp(-Dlt / T) * RAND_MAX <= rand()) swap(cf[x], cf[x - 1]);
		T *= dlt;
	}
}

int main()
{
	//freopen(".in", "r", stdin); freopen(".out", "w", stdout);
	srand(19491001); srand(rand()); srand(rand());
	n = gi <int> (); rep(i, 1, n) a[i] = gi <int> (), cf[i] = a[i] - a[i - 1];
	if (n == 1) return puts("0"), !!0;
	if (n == 2) return printf("%d\n", n * (a[1] * a[1] + a[2] * a[2]) - (a[1] + a[2]) * (a[1] + a[2])), !!0;
	while (1) SA();
	return !!0;
}

[JSOI2004] 平衡点 / 吊打XXX

#include <bits/stdc++.h>

#define DEBUG fprintf(stderr, "Passing [%s] line %d\n", __FUNCTION__, __LINE__)
#define File(x) freopen(x".in","r",stdin); freopen(x".out","w",stdout)
#define rep(i, x, y) for (int i = (x); i <= (y); i+=1)
#define epr(i, x) for (int i = head[x]; i; i = nxt[i])
#define per(i, x, y) for (int i = (x); i >= (y); i-=1)
#define DC int T = gi <int> (); while (T--)
#define Add(a, b) a = (a + b) % mod
#define chkmin(a, b) a = min(a, b)
#define chkmax(a, b) a = max(a, b)
#define pb push_back
#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int, int> PII;
typedef pair <LL, int> PLI;
typedef pair <int, LL> PIL;
typedef pair <LL, LL> PLL;

template <typename T>
inline T gi()
{
	T x = 0, f = 1; char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return f * x;
}

const int N = 1003, M = N << 1;
const double dlt = 0.9975, eps = 1e-14;

int n;
int x[N], y[N], w[N];
double ansx, ansy, tx, ty, ans = 1e18;

inline double query(double xx, double yy)
{
	double res = 0;
	rep(i, 1, n)
	{
		double dx = xx - x[i], dy = yy - y[i];
		res += sqrt(dx * dx + dy * dy) * w[i];
	}
	return res;
}

inline void SA()
{
	double T = 2000;
	while (T > eps)
	{
		if ((double)clock() / CLOCKS_PER_SEC >= 0.993) {printf("%0.3lf %.3lf\n", ansx, ansy); exit(0);}
		double nx = tx + (rand() * 2 - RAND_MAX) * T, ny = ty + (rand() * 2 - RAND_MAX) * T;
		double tans = query(nx, ny), Dlt = tans - ans;
		if (Dlt < 0) ans = tans, ansx = tx = nx, ansy = ty = ny;
		else if (exp(-Dlt / T) * RAND_MAX > rand()) tx = nx, ty = ny;
		T *= dlt;
	}
}

int main()
{
	//freopen(".in", "r", stdin); freopen(".out", "w", stdout);
	srand(19491001); srand(rand()); srand(rand());
	n = gi <int> (); rep(i, 1, n) x[i] = gi <int> (), y[i] = gi <int> (), w[i] = gi <int> (), ansx += x[i], ansy += y[i];
	ansx /= n, ansy /= n;
	tx = ansx, ty = ansy;
	while (1) SA();
	printf("%.3lf %.3lf\n", ansx, ansy);
	return !!0;
}

标签:__,typedef,long,模拟退火,模板,pair,gi,define
来源: https://www.cnblogs.com/xsl19/p/Simulate-Anneal-templates.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有