题目描述

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

输入输出格式

输入格式:

输入文件data.in包括:

第一行是两个整数,表示N,M的值(N是整数个数,M是要分成的组数)

第二行有N个整数,表示A1、A2、……、An。整数的范围是1--50。

(同一行的整数间用空格分开)

输出格式:

输出文件data.out包括一行,这一行只包含一个数,表示最小均方差的值(保留小数点后两位数字)。

输入输出样例

输入样例#1:

6 3

1 2 3 4 5 6

输出样例#1:

0.00

说明

样例解释:1和6、2和5、3和4分别为一组

【数据规模】

对于40%的数据,保证有K<=N <= 10,2<=K<=6

对于全部的数据,保证有K<=N <= 20,2<=K<=6

题解

  • 看到大部分人都写模拟退火+dp,但是我太蒻了,懒得dp(其实是不会),于是一波模拟退火+贪心调参最终A掉(心累)
  • 这道题其实是不太好写的,因为题目只给了我们组数,需要我们自己分组,所以对于模拟退火来说,就只能随机分组
  • 因为题目需要我们的均方差最小,这肯定需要我们有一个最优的分组,当温度较高时,答案还不是特别稳定,那么我们应该可以想到一个贪心,随机找一个元素,然后在整个分组中找一个当前总和最小的分组,把它加进去,再检查答案,如果当前更优,就更新,否则我们就以一定几率来接受它.而当温度较低时,这时答案已经比较稳定,即答案都差不多大,再使用贪心并没有多大作用,因此我们可以随机选出分组进行更新,更新方法还是和上面一样
  • 因为模拟退火是随机算法,我们可以在时间复杂度允许的情况下运行多次,保证找到最优解

Code

#include<bits/stdc++.h>
#define in(i) (i=read())
using namespace std;
const double delta=0.98;
int read() {
int ans=0,f=1; char i=getchar();
while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
while(i>='0' && i<='9') {ans=(ans<<1)+(ans<<3)+i-'0'; i=getchar();}
return ans*f;
}
int n,m;
double t,ave,minx=2147483647;
double sum[21];
int belong[21];
int a[21];
void work() {
memset(sum,0,sizeof(sum));
double ans=0,T=1024.0;
for(int i=1;i<=n;i++) {
belong[i]=rand()%m+1;
sum[belong[i]]+=a[i];
}
for(int i=1;i<=m;i++) ans+=(sum[i]-ave)*(sum[i]-ave);
while(T>1e-2) {
int t=rand()%n+1,x=belong[t],y;
if(T>35) y=min_element(sum+1,sum+1+m)-sum;
else y=rand()%m+1;
if(x==y) continue;
double preans=ans;
ans-=(sum[x]-ave)*(sum[x]-ave);
ans-=(sum[y]-ave)*(sum[y]-ave);
sum[x]-=a[t],sum[y]+=a[t];
ans+=(sum[x]-ave)*(sum[x]-ave);
ans+=(sum[y]-ave)*(sum[y]-ave);
if(ans<=preans) belong[t]=y;
else if(exp((ans-preans)/T)*RAND_MAX>rand()) {
sum[x]+=a[t],sum[y]-=a[t];
ans=preans;
}
else belong[t]=y;
T*=delta;
}
minx=min(ans,minx);
}
int main()
{
srand(time(0));
in(n); in(m);
for(int i=1;i<=n;i++) {
in(a[i]); ave+=a[i];
}
ave/=(double)m;
for(int i=1;i<=1024;i++) work();
printf("%.2lf\n",sqrt(minx/m));
return 0;
}

博主蒟蒻,随意转载.但必须附上原文链接

http://www.cnblogs.com/real-l/

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. BZOJ 2428 JZYZOJ1533 : [HAOI2006]均分数据 模拟退火 随机化

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

  5. P2503 [HAOI2006]均分数据

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

  6. bzoj2428: [HAOI2006]均分数据

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

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

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

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

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

  9. [luogu2503][HAOI2006]均分数据【模拟退火】

    题目描述 已知N个正整数:A1.A2.--.An .今要将它们分成M组,使得各组数据的数值和最平均,即各组的均方差最小.均方差公式如下: 分析 模拟退火学习笔记:https://www.cnblogs ...

随机推荐

  1. java web项目使用ant编译将不同的功能代码打包成jar,进而分局点将项目打包成不同的tar.gz包进而部署

    使用ant可以轻松的将一个项目分离代码,直接打包成不同需求的tar.gz包使用 1.build.properties (属性) version.num=1.0 #版本信息 2.build.xml (a ...

  2. 分支push不上去的问题

    还原一下现场,我在自己的项目里面,从master里面checkout的一个分支,当我在我这个分支里面进行 push代码的操作,我突然发现我的代码不能执行push的操作,如图 这个原因是由于远端的仓库没 ...

  3. Spring中的设计模式--观察者模式

    spring在容器中使用了观察者模式: 一.spring事件:ApplicationEvent,该抽象类继承了EventObject类,jdk建议所有的事件都应该继承自EventObject. 二.s ...

  4. Java面试题集合

    1.Java的HashMap是如何工作的? HashMap是一个针对数据结构的键值,每个键都会有相应的值,关键是识别这样的值. HashMap 基于 hashing 原理,我们通过 put ()和 g ...

  5. LARK BOARD开发板入门学习-第2篇

    1. 本次主要研究下HDMI接口,使用芯片是CH7033,这个芯片可以接VGA和HDMI两种接口,和FPGA的接口是地址数据总线 2. 值得注意的地方,下图的D1,双二极管BAT54S在电路中一般用于 ...

  6. 管理员常用Windows PowerShell命令Top25

    即使Windows PowerShell已经由来已久,但很多管理员并不愿意主动熟悉PowerShell cmdlet命令行.随着微软扩展了PowerShell的功能,管理员应该对其功能及使用烂熟于心. ...

  7. JVM运行内存分配和回收

    本文来自网易云社区 作者:吕宗胜 Java语言与C语言相比,最大的特点是编程人员无需过多的关心Java的内存分配和回收,因为所有这一切,Java的虚拟机都帮我们实现了.JVM的内存管理,大大降低了开发 ...

  8. beanshell引用参数化数据

    步骤: 1.添加参数化组件CSV Data Set  Config: 2.添加beanshell preprocessor,引用变量: 验证: 2个线程,迭代2次,分别取了4个不同的值.

  9. tensorflow nmt基本配置(tf-1.4)

    随着tensorflow的不断更新,直接按照nmt的教程搭建nmt环境会报错的...因此,需要一些不太好的办法来避免更多的问题出现.tensorflow看来在ubuntu和debian中运行是没有问题 ...

  10. 为 Ubuntu/Anaconda/pip 添加国内下载源

    背景 正在看 tensorflow-lite 压缩模型的部分,结果 tutorial 一上来就要卸旧版安装 tf-nightly (新版?反正小白下就vans了) 然而好不容易才编译好源码舍不得删.又 ...