题目描述

现在有n枚金币,它们可能会有不同的价值,现在要把它们分成两部分,要求这两部分金币数目之差不超过1,问这样分成的两部分金币的价值之差最小是多少?

分析

根据模拟退火的基本套路,先随机分两堆金币,然后每一次随机从两堆中取出一个,进行交换,看看答案是否更优【太简单了,不多赘述】

ac代码

#include <bits/stdc++.h>
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
#define db double
using namespace std;
inline char gc() {
    static char buf[1 << 16], *S, *T;
    if (S == T) {
        T = (S = buf) + fread(buf, 1, 1 << 16, stdin);
        if (T == S) return EOF;
    }
    return *S ++;
}
template <typename T>
inline void read(T &x) {
    T w = 1;
    x = 0;
    char ch = gc();
    while (ch < '0' || ch > '9') {
        if (ch == '-') w = -1;
        ch = gc();
    }
    while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc();
    x = x * w;
}
template <typename T>
void write(T x) {
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) write(x / 10);
    putchar(x % 10 + 48);
}
#define N 105
int n, ans;
int a[N];
int calc() {
    int res1 = 0, res2 = 0;
    for (int i = 1; i <= n; i ++)
        if (i <= (n + 1) / 2) res1 += a[i];
        else res2 += a[i];
    return abs(res1 - res2);
}
db Rand() {
    return rand() % 10000 / 10000.0;
}
void SA(db T) {
    while (T > 1e-3) {
        int x = rand() % ((n + 1) / 2) + 1, y = rand() % ((n + 1) / 2) + ((n + 1) / 2);
        if (x <= 0 || x > n || y <= 0 || y > n) continue;
        swap(a[x], a[y]);
        int res = calc();
        if (ans > res) ans = res;
        else if ((exp((1.0 * ans - 1.0 * res) / T)) <= Rand()) swap(a[x], a[y]);
        T *= 0.98;
    }
}
int main() {
//  freopen("coin.in","r",stdin);
//  freopen("coin.out","w",stdout);
    srand(15346301);
    int cas;
    read(cas);
    for (int _t = 1; _t <= cas; _t ++) {
        read(n);
        for (int i = 1; i <= n; i ++) read(a[i]);
        ans = inf;
        for (int i = 1; i <= 150; i ++) SA(10000);
        printf("%d\n", ans);
    }
    return 0;
}

[luogu3878][TJOI2010]分金币【模拟退火】的更多相关文章

  1. [Luogu3878] [TJOI2010]分金币

    题目描述 现在有n枚金币,它们可能会有不同的价值,现在要把它们分成两部分,要求这两部分金币数目之差不超过1,问这样分成的两部分金币的价值之差最小是多少? 输入输出格式 输入格式: 每个输入文件中包含多 ...

  2. Luogu-3878 [TJOI2010]分金币

    这题和在我长郡考试时的一道题思路差不多...考虑折半搜索,预处理左半边选的方案所产生的数量差值\(x\)以及价值差值\(y\),把\(y\)扔到下标为\(x\)的set里面,然后在搜索右半边,每搜出一 ...

  3. luogu P3878 [TJOI2010]分金币

    [返回模拟退火略解] 题目描述 今有 nnn 个数 {ai}\{a_i\}{ai​},把它们分成两堆{X},{Y}\{X\},\{Y\}{X},{Y},求一种分配使得∣∑i∈Xai−∑i∈Yai∣|\ ...

  4. [TJOI2010]分金币

    嘟嘟嘟 看数据范围,就能想到折半搜索. 但怎么搜,必须得想清楚了. 假设金币总数为1000,有20个人,首先搜前10个人,把答案记下来.然后如果在后十个人中搜到了4个人,价值为120,那么我们应该在记 ...

  5. [洛谷P3878][TJOI2010]分金币

    题目大意:把$n(n\leqslant30)$个数分成两组,两组个数最多相差$1$,求出两组元素差的绝对值最小使多少 题解:模拟退火 卡点:$\exp$中的两个数相减写反,导致$\exp(x)$中的$ ...

  6. 分金币 bzoj 3293

    分金币(1s 128M)  coin [问题描述] 圆桌上坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等.你的任务是求出被转手的 ...

  7. 【BZOJ-3293&1465&1045】分金币&糖果传递×2 中位数 + 乱搞

    3293: [Cqoi2011]分金币 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 854  Solved: 476[Submit][Status] ...

  8. 【贪心+中位数】【UVa 11300】 分金币

    (解方程建模+中位数求最短累积位移) 分金币(Spreading the Wealth, UVa 11300) 圆桌旁坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一 ...

  9. 【BZOJ3293】分金币(贪心)

    [BZOJ3293]分金币(贪心) 题面 BZOJ 洛谷 题解 和上一题一样啊. #include<cstdio> #include<cmath> #include<al ...

随机推荐

  1. Linux kernel support docker storage driver aufs

    How to make docker use aufs in CentOS 7? - Server Faulthttps://serverfault.com/questions/650208/how- ...

  2. IdentityServer4【QuickStart】之使用asp.net core Identity

    使用asp.net core Identity IdentityServer灵活的设计中有一部分是可以将你的用户和他们的数据保存到数据库中的.如果你以一个新的用户数据库开始,那么,asp.net co ...

  3. [日志]SAP S/4 HANA 启动与关闭的顺序

    注意 如果是非正式版的话 修改了日期了  需要重启一下应用和数据库才可以, S/4 HANA 启动步骤 先启动HANA: 在终端里输入 su - hdbadm HDB start 再启动S4 su - ...

  4. 在Laravel中使用数据库事务以及捕获事务失败后的异常

    Description 在Laravel中要想在数据库事务中运行一组操作,则可以在 DB facade 中使用 transaction 方法.如果在事务的闭包内抛出异常,事务将会被自动还原.如果闭包运 ...

  5. centOS7搭建NFS服务器

    借鉴别人这篇博客搭建成功的:http://blog.51cto.com/mrxiong2017/2087001 NFS系统:用来共享文件.图片.视频 准备两个centOS7服务器,一个作NFS ser ...

  6. 在python中定义二维数组

    发表于 http://liamchzh.0fees.net/?p=234&i=1 一次偶然的机会,发现python中list非常有意思. 先看一段代码 [py]array = [0, 0, 0 ...

  7. JAVA 变量 数据类型 运算符 知识小结

    ---------------------------------------------------> JAVA 变量 数据类型 运算符 知识小结 <------------------ ...

  8. 使用layui 做后台管理界面,在Tab中的链接点击后添加一个新TAB的解决方法

    给链接或按钮  添加 onclick="self.parent.addTab('百度','http://www.baidu.com','icon-add')" 如: <a h ...

  9. darknet源码解析

    https://blog.csdn.net/u014540717/article/category/6513159

  10. aop通配符语法

    *.表示通配包名  *. == com. com.rl.ecps.service == *.*.*.*. ..表示 通配任何包及其子包   例如 com.. ==com. *.*.*. com.rl. ...