题目描述

已知N个正整数:A1、A2、……、An 。今要将它们分成M组,使得各组数据的数值和最平均,即各组的均方差最小。均方差公式如下:

分析

模拟退火学习笔记:https://www.cnblogs.com/chhokmah/p/10529114.html
万物皆可颓火,我们首先将初始的答案当做一半一半的答案,然后我们随机化抽取两个部分的数据。根据题目中的描述,因为两个组别之间数据个数只能是差一,那么差不多就是一半一半的情况。那么我们就只需要分块两部分,然后随机交换,如果两个数据交换之后能使答案能更优,那么就交换,如果不能让我们的答案变得更加优,那么就让随机概率,这个概率很明显是越到后面交换的概率越小,那么我们就是exp(delta) < t * Rand(),那么就交换,否则就不交换。
模拟退火的精髓还是这个调参,这道题目我一遍A掉了,感觉有一点欧皇。
我给出一个比较优秀的随机种子,是ouhuang和6666666的取模,就是15346301。

ac代码

#include <bits/stdc++.h>
#define ms(a,b) memset(a, b, sizeof(a))
#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 305
db ans = 1e30, ave = 0;
int sum[N], pos[N], a[N];
int n, m;
void SA(db T){
    ms(sum, 0);
    for (int i = 1; i <= n; i ++) {
        pos[i] = rand() % m + 1;
        sum[pos[i]] += a[i];
    }
    db res = 0;
    for (int i = 1; i <= m; i ++)
        res += (1.0 * sum[i] - ave) * (1.0 * sum[i] - ave);
    while (T > 1e-4) {
        int t = rand() % n + 1, x = pos[t], y;
        if (T > 500) y = min_element(sum + 1, sum + 1 + m) - sum;
        else y = rand() % m + 1;
        if (x == y) continue;
        db tmp = res;
        res -= (sum[x] - ave) * (sum[x] - ave);
        res -= (sum[y] - ave) * (sum[y] - ave);
        sum[x] -= a[t], sum[y] += a[t];
        res += (sum[x] - ave) * (sum[x] - ave);
        res += (sum[y] - ave) * (sum[y] - ave);
        if (res < tmp || rand() % 10000 <= T) pos[t] = y;
        else sum[x] += a[t], sum[y] -= a[t], res = tmp;
        ans = min(ans, res);
        T *= 0.98;
    }
}
int main() {
    srand(20040127);
    read(n); read(m);
    for (int i = 1; i <= n; i ++) {
        read(a[i]);
        ave += 1.0 * a[i];
    }
    ave /= 1.0 * m;
    for (int i = 1; i <= 1500; i ++) SA(10000);
    printf("%.2lf\n", sqrt(ans / m));
    return 0;
}

[luogu2503][HAOI2006]均分数据【模拟退火】的更多相关文章

  1. bzoj2428 [HAOI2006]均分数据 模拟退火

    [HAOI2006]均分数据 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 3434  Solved: 1091[Submit][Status][Dis ...

  2. 洛谷P2503 [HAOI2006]均分数据(模拟退火)

    题目描述 已知N个正整数:A1.A2.…….An .今要将它们分成M组,使得各组数据的数值和最平均,即各组的均方差最小.均方差公式如下: 输入输出格式 输入格式: 输入文件data.in包括: 第一行 ...

  3. BZOJ2428[HAOI2006]均分数据——模拟退火

    题目描述 已知N个正整数:A1.A2.…….An .今要将它们分成M组,使得各组数据的数值和最平均,即各组的均方差最小.均方差公式如下: ,其中σ为均方差,是各组数据和的平均值,xi为第i组数据的数值 ...

  4. HAOI2006 均分数据 [模拟退火]

    题目描述 已知N个正整数:A1.A2.--.An .今要将它们分成M组,使得各组数据的数值和最平均,即各组的均方差最小.均方差公式如下: 输入输出格式 输入格式: 输入文件data.in包括: 第一行 ...

  5. BZOJ 2428 JZYZOJ1533 : [HAOI2006]均分数据 模拟退火 随机化

    http://www.lydsy.com/JudgeOnline/problem.php?id=2428 http://172.20.6.3/Problem_Show.asp?id=1533 http ...

  6. P2503 [HAOI2006]均分数据

    P2503 [HAOI2006]均分数据 模拟退火+dp (不得不说,我今天欧气爆棚) 随机出1个数列,然后跑一遍dp统计 #include<iostream> #include<c ...

  7. bzoj2428: [HAOI2006]均分数据

    模拟退火.挺好理解的.然后res打成了ans一直WA一直WA...!!!一定要注意嗷嗷嗷一定要注意嗷嗷嗷一定要注意嗷嗷嗷. 然后我就一直卡一直卡...发现最少1800次的时候就可以出解了.然后我就去调 ...

  8. 洛谷 P2503 [HAOI2006]均分数据 随机化贪心

    洛谷P2503 [HAOI2006]均分数据(随机化贪心) 现在来看这个题就是水题,但模拟赛时想了1个小时贪心,推了一堆结论,最后发现贪心做 不了, 又想了半个小时dp 发现dp好像也做不了,在随机化 ...

  9. bzoj 2428: [HAOI2006]均分数据 随机化

    2428: [HAOI2006]均分数据 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...

随机推荐

  1. django的配置文件字符串是怎么导入的?

    写在开头: 每个APP都会有配置文件,像下代码Django等等这种的settings里面的配置导入都是字符串的,他们是怎么做的呢? MIDDLEWARE = [ 'django.middleware. ...

  2. 关于js作用域问题

    补充: function Foo(name,age){ this.name=name; this.age=age; this.getName=function(){ console.log(this) ...

  3. 软件工程(FZU2015) 增补作业

    SE_FZU目录:1 2 3 4 5 6 7 8 9 10 11 12 13 说明 张老师为FZU软件工程2015班级添加了一次增补作业,总分10分,deadline是2016/01/01-2016/ ...

  4. HashSet中存放不重复元素

    一.自定义对象存放在hashSet中,保证元素不重复.重写hashCode()和equals()方法 public class Student{ private String name; privat ...

  5. EF内容记录_EF连接Mysql版本问题

    EF连接MySQL可用版本,由于EF.MySQLConnection.mysql-for-visualstudio.VS版本.MySQL.Data.MySQL.Data.Entity版本问题较花时间, ...

  6. react 路由4 学习

    表单控件 受控表单组件 非受控的表单组件 demo:收集表单提交的数据 路由(V4) 特点:一切皆是组件 官网:https://reacttraining.com/react-router/ npm ...

  7. Windows 激活的简单办法(能上网)

    1. 之前很多机器上面总是提示我  盗版系统看起来挺不high的 2. 还是使用之前的办法来进行激活 slmgr  (之前写过) /ipk <Product Key> 安装产品密钥(替换现 ...

  8. MHA高可用及读写分离

    一.MHA简介 二.工作流程 三.MHA架构图 四.MHA工具介绍 五.基于GTID的主从复制 六.部署MHA 七.配置VIP漂移 八.配置binlog-server 九.MySQL中间件Atlas

  9. 在浏览器上安装 Vue Devtools工具

    Vue.js devtools是基于google chrome浏览器的一款调试vue.js应用的开发者浏览器扩展,可以在浏览器开发者工具下调试代码. 1)首先在github下载devtools源码,地 ...

  10. python爬虫scrapy之登录知乎

    下面我们看看用scrapy模拟登录的基本写法: 注意:我们经常调试代码的时候基本都用chrome浏览器,但是我就因为用了谷歌浏览器(它总是登录的时候不提示我用验证码,误导我以为登录时不需要验证码,其实 ...