您的位置:首页 > 其它

[bzoj2428] [HAOI2006]均分数据

2016-03-21 13:04 211 查看
  模拟退火。。

  随机每个数是属于哪一组的就可以了。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
#define d double
using namespace std;
int sm[7],bel[21],a[21];
int i,j,k,n,m;
d avg,sqr[1023],mn;
int ra;char rx;
inline int read(){
rx=getchar(),ra=0;
while(rx<'0'||rx>'9')rx=getchar();
while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
}
inline void run(){
d T=10023;register int i;d ans=0,tmp;
int j,x,y;
for(i=0;i<m;i++)sm[i]=0;
for(i=0;i<n;i++)sm[bel[i]=rand()%m]+=a[i];
for(i=0;i<m;i++)ans+=sqr[sm[i]];
//    for(i=0;i<m;i++)printf("  %d",sm[i]);puts("");printf("   %.2lf\n",ans);
while(T>0.1){
T*=0.9;
x=bel[j=rand()%n];
if(T<500)y=rand()%m;else
for(i=1,y=0;i<m;i++)if(sm[i]<sm[y])y=i;

if(x==y)continue;
//    for(i=0;i<m;i++)printf("  %d",sm[i]);puts("");
tmp=ans-sqr[sm[y]]-sqr[sm[x]]+sqr[sm[y]+a[j]]+sqr[sm[x]-a[j]];
//    printf("move:%d  %d-->%d    %.2lf\n",j,bel[j],k,tmp);
if(tmp<=ans||(rand()%10000<T))
sm[x]-=a[j],bel[j]=y,sm[y]+=a[j],ans=tmp;
}
if(ans<mn)mn=ans;
}
int main(){
n=read(),m=read();
for(i=0;i<n;i++)a[i]=read(),avg+=a[i];
avg/=m;
for(i=0;i<=1000;i++)sqr[i]=(i-avg)*(i-avg);//,printf("%d %.2lf\n",i,sqr[i]);
mn=1e23;
for(i=10023;i&&mn>1e-7;i--)run();
printf("%.2lf\n",sqrt(mn/m));
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: