【BZOJ2428】[HAOI2006]均分数据
2016-01-24 21:52
357 查看
Description
已知N个正整数:A1、A2、……、An 。今要将它们分成M组,使得各组数据的数值和最平均,即各组的均方差最小。均方差公式如下:,其中σ为均方差,是各组数据和的平均值,xi为第i组数据的数值和。
Input
第一行是两个整数,表示N,M的值(N是整数个数,M是要分成的组数)第二行有N个整数,表示A1、A2、……、An。整数的范围是1--50。
(同一行的整数间用空格分开)
Output
这一行只包含一个数,表示最小均方差的值(保留小数点后两位数字)。Sample Input
6 31 2 3 4 5 6
Sample Output
0.00HINT
对于全部的数据,保证有K<=N <= 20,2<=K<=6传说中的模拟退火裸题,此处OTZ CA 爷
在我看来模拟退火就是一种特别看人品的贪心,不停地取随机数,也不知道最后能不能用上,毕竟我人品超级差
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<cstdlib> #include<algorithm> using namespace std; int n,m,sum1; int a[30],grp[30]; double sum[30],tmp,minn=10000000,ave=0; double sqr(double x) { return x*x; } void solve(){ memset(sum,0,sizeof(sum));tmp=0; for (int i=1;i<=n;i++) grp[i]=rand()%m+1; for (int i=1;i<=n;i++) sum[grp[i]]+=a[i]; for (int i=1;i<=m;i++) tmp+=sqr(sum[i]-ave); double T=17500; while (T>0.1){ T*=0.9; int t=rand()%n+1,x=grp[t],y; if (T>500) y=min_element(sum+1,sum+m+1)-sum; else y=rand()%m+1; if (x==y) continue; double last=tmp; tmp-=sqr(sum[x]-ave);tmp-=sqr(sum[y]-ave); sum[x]-=a[t];sum[y]+=a[t]; tmp+=sqr(sum[x]-ave);tmp+=sqr(sum[y]-ave); if (rand()%10000>T&&tmp>last) sum[x]+=a[t],sum[y]-=a[t],tmp=last; else grp[t]=y; } minn=min(minn,tmp); } int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++)scanf("%d",&a[i]), sum1+=a[i],swap(a[i],a[rand()%i+1]); ave=(sum1+0.0)/m; for (int i=1;i<=10000;i++) solve(); printf("%.2lf\n",sqrt(minn/m)); }
相关文章推荐
- Node.js权威指南 (3) - Node.js基础知识
- scala习题(12)——高阶函数
- Mesos入门介绍
- 小蚂蚁学习数据结构(23)——伪代码中的引用
- 磁盘管理
- Linux主流架构运维工作简单剖析
- MongoDB的三种启动方式
- 我理解c#中的interface abstract virtual override和new
- 黑客专用 Linux 发行版 Kali Linux 发布了首个滚动更新版 2016.1
- emacs如何配置彩虹猫模式
- 《Learn You Some Erlang for Great Good!》的学习笔记(三)
- Node.js权威指南 (2) - Node.js中的交互式运行环境——REPL
- Node.js权威指南 (1) - Node.js介绍
- PHP——数组中的each(),list()和while循环遍历数组
- 深度学习开发工具
- 寒假练习一
- C#去除字符串空格的几种方法1.
- Media Query媒体查询
- php 2015 年最热门的 10 篇技术文章
- RecyclerView初学