bzoj2428: [HAOI2006]均分数据
Posted akcqhzdy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2428: [HAOI2006]均分数据相关的知识,希望对你有一定的参考价值。
垃圾bzoj本机AC提交WA,精A
%你退火可解
因为n很小所以我们可以降温慢点,为了更优我们先在开始的时候选择一个数贪心地放到总和最小地那一组
然后就是不停换随机种子T_T
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; double sqr(double x){return x*x;} double drand(){return double(rand()%10000)/10000.0;} int n,m,p[30];double a[30],mmin; double sum[30]; double calc() { memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++)sum[p[i]]+=a[i]; double ave=0; for(int i=1;i<=m;i++)ave+=sum[i]; ave/=double(m); double ret=0; for(int i=1;i<=m;i++)ret+=sqr(ave-sum[i]); ret=sqrt(ret/(double)m); if(ret<mmin)mmin=ret; return ret; } void annealing() { double T=1000000.0; while(T>1) { double k1=calc(); int pp=1; for(int i=1;i<=m;i++) if(sum[i]<sum[pp])pp=i; int x=rand()%n+1,np; while(p[x]==pp){x++;if(x==n+1)x=1;} np=p[x],p[x]=pp; double k2=calc(); if(k1>k2||exp((k1-k2)/T)>drand()); else p[x]=np; T*=0.9997; } while(T>0.0001) { int x=rand()%n+1,pp=rand()%m+1,np; if(pp==p[x]){pp++;if(pp==m+1)pp=1;} double k1=calc(); np=p[x],p[x]=pp; double k2=calc(); if(k1>k2||exp((k1-k2)/T)>drand()); else p[x]=np; T*=0.9997; } for(int i=1;i<=1000;i++) { int x=rand()%n+1,pp=rand()%m+1,np; if(pp==p[x]){pp++;if(pp==m+1)pp=1;} double k1=calc(); np=p[x],p[x]=pp; double k2=calc(); p[x]=np; } } int main() { srand(25424); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lf",&a[i]), p[i]=rand()%m+1; random_shuffle(a+1,a+n+1); mmin=calc(); annealing(); printf("%.2lf",mmin); return 0; }
以上是关于bzoj2428: [HAOI2006]均分数据的主要内容,如果未能解决你的问题,请参考以下文章