2428: [HAOI2006]均分数据

原创 2016年08月31日 13:53:58

2428: [HAOI2006]均分数据

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 1660  Solved: 500
[Submit][Status][Discuss]

Description

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

,其中σ为均方差,是各组数据和的平均值,xi为第i组数据的数值和。

 

Input

第一行是两个整数,表示N,M的值(N是整数个数,M是要分成的组数)
第二行有N个整数,表示A1、A2、……、An。整数的范围是1--50。
(同一行的整数间用空格分开)

Output

这一行只包含一个数,表示最小均方差的值(保留小数点后两位数字)。

Sample Input

6 3
1 2 3 4 5 6

Sample Output

0.00

HINT

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

Source

Day2

[Submit][Status][Discuss]

RP算法--模拟退火
主要思路如下:
随机选出一组解,,此时可能离正解很遥远,我们随机地去更新,随着时间的推移,这个解离正解的距离也会越来越近,最后停止,即得出正解
一开始随意地把元素置入各个分组,每次随机一个元素,将它放到别的组里面去,一开始我们可能离正解很远,就贪心找一个当前元素和最小的分组,把这个元素放进去,看能不能更优,随着时间的推移,离正解越来越近,此时贪心不一定可行,就随机一个分组,把这个元素放进去
当改变了一个元素所属分组,如果新的ans优于当前的,就接受它,否则以一定概率接受它,这个概率一定是随着时间推移不断降低的
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#include<cmath>
#include<ctime>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;

typedef double DB;

int n,m,a[22],belong[22];
DB Ave,ans = 1E18,sum[10];

DB Pow(DB x) {return x*x;}
void Fire()
{
	for (int i = 1; i <= m; i++)
		sum[i] = 0;
	for (int i = 1; i <= n; i++) {
		int Num = rand()%m + 1;
		sum[Num] += a[i];
		belong[i] = Num;
	}
	DB Now = 0;
	for (int i = 1; i <= m; i++)
		Now += Pow(sum[i] - Ave);
	
	DB T = 10000;
	while (T > 0.1) {
		T *= 0.9;
		int x = rand()%n + 1;
		DB tmp = Now,k = a[x];
		int A = belong[x],B;
		if (T > 500) {
			DB Min = 1E18;
			for (int i = 1; i <= m; i++)
				if (sum[i] < Min)
					Min = sum[i],B = i;
		}
		else B = rand()%m + 1;
		if (A == B) continue;
		Now -= Pow(sum[A] - Ave);
		Now -= Pow(sum[B] - Ave);
		sum[A] -= k;
		sum[B] += k;
		Now += Pow(sum[A] - Ave);
		Now += Pow(sum[B] - Ave);
		if (Now > tmp) {
			int pass = rand()%10000;
			if (pass > T) {
				sum[A] += k;
				sum[B] -= k;
				Now = tmp;
				continue;
			}
		}
		belong[x] = B;
	}
	ans = min(ans,Now);
}

int main()
{
	#ifdef DMC
		freopen("DMC.txt","r",stdin);
	#endif
	
	//srand(19990720);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		scanf("%d",&a[i]);
		Ave += (DB)(a[i]);
	}
	Ave /= (DB)(m);
	for (int i = 1; i <= 10000; i++) 
		Fire();
	printf("%.2lf",sqrt(ans/(DB)(m)));
	return 0;
}

版权声明:这个人很懒什么都没有留下

相关文章推荐

武汉新迪数字工程系统有限公司招聘 C++软件工程师 软件培训工程师

武汉新迪数字工程系统有限公司 新迪数字工程系统有限公司总部位于杭州,是一家以技术立本的软件研发和技术服务型公司,秉承“数字科技服务中国制造业”的创业宗旨,公司始终坚持不断技术创新,目前已形...

Codeforces Round #336 (Div. 1) D. Power Tree

D. Power Tree time limit per test 3.5 seconds memory limit per test 256 megabytes i...

QPBOC交易流程详解--POS与卡片的数据交互进行分析

很多人都容易混淆了QPBOC,PBOC和电子现金、电子钱包的概念。首先,电子钱包早在PBOC2.0的规范里面就去掉了,在PBOC3.0里面把MSD也去掉了。因此,最新的PBOC3.0规范里面,定义了三...

进程间通信

进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。但是,系统空间 却是“公共...

How to Monitor UGA, PGA and Cursor Usage Per Session. [ID 551198.1]

How to Monitor UGA, PGA and Cursor Usage Per Session. [ID 551198.1] Modified 26-MAY-2008     Type HO...

洛谷P2503 BZOJ2428 [HAOI2006]均分数据

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

bzoj 2428 [HAOI2006]均分数据

Description 已知N个正整数:A1、A2、……、An 。今要将它们分成M组,使得各组数据的数值和最平均,即各组的均方差最小Solution 这题一眼看不会做啊,这题肯定是乱搞题啊。。。一...

模拟退火——BZOJ2428/Luogu2503 [HAOI2006]均分数据

题面:Luogu2503 BZOJ2428 这题使用其他的常规算法不太现实,所以我们想一些奇怪的方法 模拟退火其实就可以(这题拿来入门了) 我们首先把每个数随机分组,然后随机地把一个数从原来的组...

[BZOJ2428][HAOI2006]均分数据(模拟退火)

ATP今晚要不要请假回家睡觉呢。。。

BZOJ2428 [HAOI2006]均分数据(模拟退火算法)

【题解】 随机10000次左右,每次随机生成初始分组情况,判断将某个元素移入另一组是否会更优,记录全局最优答案  注意: 1. 自己用平方取中法弄的伪随机数,效果远不如系统函数rand() ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)