题目描述

已知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. 数据库中pymysql模块的使用

    pymysql 模块 使用步骤: 核心类Connect链接用和Cursor读写用 1. 与数据库服务器建立链接 2. 获取游标对象(用于发送和接收数据) 3. 用游标执行sql语句 4. 使用fetc ...

  2. POJ1985 树的直径(BFS

    Cow Marathon   Description After hearing about the epidemic of obesity in the USA, Farmer John wants ...

  3. P1331 海战

    P1331 海战 题目描述 在峰会期间,武装部队得处于高度戒备.警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞机.此外,巡洋船只和舰队将被派去保护海岸线.不幸的是因为种种原因,国防 ...

  4. 从C到C++ (3)

    从C到C++ (3) 一.    C++中增加了引用 1.引用是给某一个变量起别名.引用的一般格式: 类型 &引用名 = 变量名 定义引用时一定要初始化.在实际应用中,引用一般用作参数传递与返 ...

  5. hibernate 各历史版本下载 spring各历史版本下载

    hibernate 各历史版本下载http://sourceforge.net/projects/hibernate/files/ spring各历史版本下载http://www.springsour ...

  6. leetcode笔记--2 reverse string

    my answer: 出错点:new_list[s] = list_s[u-1-s] 这样会出错, 重点:(1) map(str, s) 函数的使用,例:ls = [1,2,3]rs = map(st ...

  7. MySQL高可用之PXC安装部署(续)

      Preface       Yesterday I implemented a three-nodes PXC,but there were some errors when proceeding ...

  8. 接口测试工具postman(二)创建新项目

    1.此次添加一个request,可以点击左上角的New的下拉选择Request,或者点击New弹出选项框点击Request 2.弹出新增request页面 3.添加请求的参数等 4.也可以直接添加新请 ...

  9. Leetcode代码补全——链表

    通过补全代码可以更深刻的体会到,链表就是一个存储方式,通过一单元的存储指向下一单元,而查看单元内容通过头部开始的指针依次遍历.这是leetcode里融合两个链表的题目,具体代码如下: #encodin ...

  10. 在阿里云上遇见更好的Oracle(二)

    从上一篇文章的反馈来看,大家还是喜欢八卦多过技术细节,那这一篇继续一些题外话,说说我对“去IOE”的看法. 对同一件事情,参与的没参与的人,讨论起来,都会有各自的立场.所以这里先申明一下,以下内容只是 ...