COGS 307 模拟退火

307. [HAOI2006] 均分数据

★★   输入文件:data.in   输出文件:data.out   简单对比
时间限制:3 s   内存限制:128 MB

【问题描述】

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

 

其中第一个公式是均方差,第二个公式是各组数据和的平均值,xi为第i组数据的数值和。

【输入格式】 
    第一行是两个整数,表示N,M的值(N是整数个数,M是要分成的组数)。
    第二行有N个整数,表示A1,A2,……,An。整数的范围是1--50。

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

【输出格式】 
    输出文件只有一行,包括一个数 ,表示最小均方差的值(保留小数点后两位数字)。

【输入样例】 
6 3 
1 2 3 4 5 6

【输出样例】

0.00

(1和6,2和5,3和4分别为一组)

【数据范围】

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

——————————————————————————————————————————————————————————————————————————

和上一题一样,模拟退火。

唯一区别在于不是两个调换位置,而是随机改变一个的归属。

——————————————————————————————————————————————————————————————————————————

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>

using namespace std;
const int maxn=21;
int n,m,he;
double ping;
int a[maxn],belong[maxn],sum[maxn],sumf[maxn],belongf[maxn];
double ans;
double getans(int *sum)
{
    double tp=0;
    for(int i=0;i<m;i++)
    tp+=(ping-sum[i])*(ping-sum[i]);
    return sqrt(tp/m);
}
bool accept(double delta,double cur)
{
    if(delta<=0)return 1;
    return rand()<exp((-delta)/cur)*RAND_MAX;
}
double solve()
{
    const double maxw=10000;
    const double dec=0.999;
    double cur=maxw;
    double tpans=ans;
    while(cur>0.01)
    {
        int c=rand()%m,b=rand()%n;
        memcpy(belongf,belong,sizeof(belong));
        memcpy(sumf,sum,sizeof(sum));
        sumf[belongf[b]]=sumf[belongf[b]]-a[b];
        sumf[c]=sumf[c]+a[b];
        belongf[b]=c;
        double tp=getans(sumf);
        if(accept(tp-tpans,cur))
        {
            tpans=tp;
            memcpy(belong,belongf,sizeof(belong));
            memcpy(sum,sumf,sizeof(sum));
        }
        cur*=dec;
    }
    return tpans;
}
int main()
{
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    srand(123645897U);
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
    {
        scanf("%d",a+i);
        int tp=rand()%m;
        sum[tp]+=a[i];
        belong[i]=tp;
        he+=a[i];
    }
    ping=(double)he/m;
    ans=getans(sum);
    int t=150;
    while(t--)
    {
        ans=min(ans,solve());
    }
    printf("%.2lf",ans);
    fclose(stdin);fclose(stdout);
    return 0;
}
时间: 2024-08-24 15:37:30

COGS 307 模拟退火的相关文章

poj-2420 A Star not a Tree?(模拟退火算法)

题目链接: A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5219   Accepted: 2491 Description Luke wants to upgrade his home computer network from 10mbs to 100mbs. His existing network uses 10base2 (coaxial) cables that allo

COGS基本法初稿

COGS基本法 序言 我们COGS人民,为建立更完善的联盟,树立正义,保障网络安宁,提供公共OJ,杜绝极少数恐怖分子对我OJ的破坏行为,并使我们自己和OIER得享自由的幸福,特为COGS制定本基本法. 第一条权利机构 权利机构由老常为领导核心的第一代领导集体及COGS QQ群的元老组成,COGS的权力机构为君主立宪制,其中老常为世袭君主,议会由首相刘易铖,长老王梦迪,内阁大臣张灵犀,外交大臣张子昂.国家工程师李冬麟组成.首相.内阁大臣.外交大臣必须由河南省实验中学有着良好素质和学习水平的学生组成

POJ 3087 Shuffle&#39;m Up(模拟退火)

Description A common pastime for poker players at a poker table is to shuffle stacks of chips. Shuffling chips is performed by starting with two stacks of poker chips, S1 and S2, each stack containing C chips. Each stack may contain chips of several

COGS——T 2739. 凯伦和咖啡

http://www.cogs.pro/cogs/problem/problem.php?pid=2739 ★★☆   输入文件:coffee.in   输出文件:coffee.out   简单对比时间限制:1 s   内存限制:512 MB [题目描述] 为了在上课时保持清醒,凯伦需要一些咖啡.咖啡爱好者凯伦想知道最佳的温度来冲煮完美的咖啡.因此,她花了一些时间阅读几本食谱,其中包括广受好评的“咖啡的艺术”. 她知道有n个食谱,其中第i个食谱建议应当在li和ri度之间冲煮以达到最佳的味道.凯伦

COGS——T 8. 备用交换机

http://www.cogs.pro/cogs/problem/problem.php?pid=8 ★★   输入文件:gd.in   输出文件:gd.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] n个城市之间有通讯网络,每个城市都有通讯交换机,直接或间接与其它城市连接.因电子设备容易损坏,需给通讯点配备备用交换机.但备用交换机数量有限,不能全部配备,只能给部分重要城市配置.于是规定:如果某个城市由于交换机损坏,不仅本城市通讯中断,还造成其它城市通讯中断,则配

COGS——C2098. Asm.Def的病毒

http://www.cogs.pro/cogs/problem/problem.php?pid=2098 ★☆   输入文件:asm_virus.in   输出文件:asm_virus.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] “这就是我们最新研制的,世界上第一种可持久化动态计算机病毒,‘创世纪’.”方教授介绍道. “哦.”主席面无表情地点点头. “‘创世纪’无法真正杀死透明计算网络,但是可以把它变成傻子.可惜透明计算网络能轻松地辨认出病毒,所以我建议……

PKU 1379 Run Away(模拟退火算法)

题目大意:原题链接 给出指定的区域,以及平面内的点集,求出一个该区域内一个点的坐标到点集中所有点的最小距离最大. 解题思路:一开始想到用随机化算法解决,但是不知道如何实现.最后看了题解才知道原来是要用模拟退火算法解决. 不过个人感觉这个算法的实现过程中仍然采用了随机化算法.二者均属于概率算法.  参考链接 Point Goto_Rand_Dir(double key,Point temp)函数中,Point temp必须得定义在参数中,不能定义在函数内部, 否则temp没有初始值,无法进行后面的

[POJ2069]Super Star(模拟退火)

题目链接:http://poj.org/problem?id=2069 题意:求一个半径最小的球,使得它可以包围住所有点. 模拟退火,圆心每次都去找最远那个点,这样两点之间的距离就是半径,那么接下来移动的方向肯定就是朝着这个最远点移动,保证比例相同且在球内的情况下移动. 不看题解想不到,这个东西有点难啊... 1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <

两种改进的模拟退火算法求解大值域约束满足问题1.0

0引言 约束满足问题(Constraint Satisfaction Problem,CSP)是人工智能研究领域中一个非常重要的分支,现已成为理论计算机科学.数学和统计物理学等交叉学科研究中的热点问题.人工智能.计算机科学和自动控制等领域中的许多问题都可以归结为约束满足问题.同时,约束满足问题在实际问题如模式识别.决策支持.物流调度及资源分配等领域也有着非常广泛的应用. CSP由一个变量集合和一个约束集合组成.每个变量都有一个非空的可能值域,每个约束描述了一个变量子集与子集内各变量的相容赋值,所