首页 > 其他分享 >P3878 [TJOI2010] 分金币

P3878 [TJOI2010] 分金币

时间:2024-03-11 11:45:27浏览次数:28  
标签:int text rnd 金币 P3878 TJOI2010 ans include

题意

有 \(n\) 枚金币,第 \(i\) 枚价值为 \(s_i\)。

分成两部分,使得两部分数量之差不超过 \(1\),求价值之差最小是多少。

Sol

模拟退火!

其实这个算法没什么好说的。

设当前最优解与当前解的差为 \(\Delta E\)。

那么当前状态发生转移的概率为 \(P(f(n)) = \begin{cases} 1, & \text{f' is better than f} \cr e ^ {\frac{\Delta E}{T}}, & \text{Otherwise}\end{cases}\)

Code

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <array>
#include <ctime>
#include <random>
using namespace std;
#ifdef ONLINE_JUDGE

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf;

#endif
int read() {
	int p = 0, flg = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-') flg = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		p = p * 10 + c - '0';
		c = getchar();
	}
	return p * flg;
}
void write(int x) {
	if (x < 0) {
		x = -x;
		putchar('-');
	}
	if (x > 9) {
		write(x / 10);
	}
	putchar(x % 10 + '0');
}
bool _stmer;

const int N = 35, inf = 1e9;

array <int, N> s;

int rci(int n) {
	int tp1 = 0, tp2 = 0;
	for (int i = 1; i <= (n + 1) / 2; i++) tp1 += s[i];
	for (int i = (n + 1) / 2 + 1; i <= n; i++) tp2 += s[i];
	return abs(tp1 - tp2);
}

void SA(int& ans, int n) {
	mt19937 rnd(time(0));
	double T = 1e4;
	while (T > 1e-9) {
		int x = rnd() % n + 1, y = rnd() % n + 1;
		swap(s[x], s[y]);
		int _ans = rci(n);
		if (_ans < ans) ans = _ans;
		else if (exp((ans - _ans) / T) * inf < rnd()) swap(s[x], s[y]);
		T *= 0.9147;
	}
}

void solve() {
	int n = read();
	for (int i = 1; i <= n; i++)
		s[i] = read();
	int ans = inf, T = 5000;
	while (T--) SA(ans, n);
	write(ans), puts("");
}

bool _edmer;
int main() {
	cerr << (&_stmer - &_edmer) / 1024.0 / 1024.0 << "MB\n";
	int T = read();
	while (T--) solve();
	return 0;
}

标签:int,text,rnd,金币,P3878,TJOI2010,ans,include
From: https://www.cnblogs.com/cxqghzj/p/18065758

相关文章

  • [SDOI2019] 移动金币(阶梯博弈)
    题面一枚金币向左移若干格等价若干个空格向右移一个金币,终状态为所有空格在最右,转换为阶梯博弈阶梯博弈每个阶梯上有若干枚石子,每次操作将同个阶梯的任意石子向下移一个阶梯,不能操作者输等价对奇数阶梯做Nim博弈先手按Nim博弈操作。若对方移动偶数阶梯,则将对方移动石子继续下......
  • 2024-01-27:用go语言,阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有N堆金币, 第i堆金币
    2024-01-27:用go语言,阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有N堆金币,第i堆金币的总重量和总价值分别是m[i]、v[i],阿里巴巴有一个承重量为T的背包,但并不一定有办法将全部的金币都装进去,他想装走尽可能多价值的金币,所有金币都可以随意分割,分割完的金币重量价值比(也就是单位......
  • P3879 [TJOI2010] 阅读理解(水题)
    [TJOI2010]阅读理解题目描述英语老师留了N篇阅读理解作业,但是每篇英文短文都有很多生词需要查字典,为了节约时间,现在要做个统计,算一算某些生词都在哪几篇短文中出现过。输入格式第一行为整数N,表示短文篇数,其中每篇短文只含空格和小写字母。按下来的N行,每行描述一篇短文......
  • 机甲战队国服无限金币ios版本
    机甲战队国服无限金币ios版本机甲战队国服无限金币ios版本机甲战队国服无限金币ios版本机甲战队国服无限金币ios版本机甲战队国服无限金币ios版本免费,专业刷金,进战队战队!!!!!!!!三天稳定1000金币,氪金党勿入,肝佬欢迎进入,目前国服金价一月免费肝1万金币,一起开黑刷金请进qq群947633......
  • 【教3妹学编程-算法题】购买水果需要的最少金币数
    3妹:“你不是真正的快乐,你的笑只是你穿的保护色”2哥 :3妹还在唱五月天的歌啊,你不知道五月天假唱,现在全网都在骂呢。3妹:知道啊,可是关我什么事,这个歌的确好听啊。2哥 :嗯嗯,不错,还以为你是脑残粉,无论黑白都只管追星呢。3妹:我是只管追歌的,歌好听就行啦。2哥 :追哥?追哪个哥,难......
  • NOIP2015普及组金币
    NOIP2015普及组金币题目数据(n<=10000)根据题目要求与我们原来学过的打印数字三角形图形很相似。数字三角形如下,数字可以对应成天数:12 34  5  67  8  9  10每天加的金币就是行坐标即可:12  23  3  34  4  4  4代码如何:#includ......
  • P3879 TJOI2010 阅读理解
    P3879TJOI2010阅读理解基本想法开一个map组成的数组,然后每篇文章分配一个map。查找的时候在每次都跑一遍。显然MLE了。改进既然如此,录入的时候直接把单词出现对应的文章编号存起来就行,就是开一个map<string,vector<int>>。但是同一篇文章会出现多个单词,需要去重,不......
  • QT实战 之翻金币游戏
    QT实战之翻金币游戏相较于原版的优化:关卡数据不是用静态的config配置,而是动态生成,每次打开的关卡都生成不同的游戏数据,增加了可玩性;关卡数据依据关卡等级的不同而生成不同难度的数据,随关卡的增加而不断提升难度;金币矩阵由原版的4*4升级为5*5,增加了游戏难度;选择关卡按钮使用......
  • 记录--实现金币飞入钱包的动画
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 效果金币从初始位置散开后逐个飞向指定位置,这是游戏中很常用的一个动画,效果如下:思路这个效果中,分成两个阶段:一定数量的金币从一个起点散开这些金币逐一飞向终点计算金币的初始散开位置生成圆周上的等......
  • 【洛谷 P2669】[NOIP2015 普及组] 金币 题解(循环)
    [NOIP2015普及组]金币题目背景NOIP2015普及组T1题目描述国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这......