BZOJ2428 HAOI2006均分数据(模拟退火)
2018-09-02 11:42
381 查看
显然可以状压dp。显然过不了。
考虑暴力模拟退火。每次随机改变一个数所属集合即可。
并不明白要怎么调参。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 21 #define T0 1E5 #define T1 1E-6 #define v 0.996 int n,m,a ,sum ,id ,size ; double ave,ans=100000000; void anneal() { for (int i=1;i<=m;i++) id[i]=i,sum[i]=a[i],size[i]=1; for (int i=m+1;i<=n;i++) id[i]=rand()%m+1,sum[id[i]]+=a[i],size[id[i]]++; double T=T0,tot=0; for (int i=1;i<=m;i++) tot+=(sum[i]-ave)*(sum[i]-ave); if (m<n) while (T>T1) { int x=rand()%n+1; while (size[id[x]]==1) x=rand()%n+1; int y=rand()%m+1; while (id[x]==y) y=rand()%m+1; if (rand()<exp((-2.0*a[x]*(a[x]-sum[id[x]]+sum[y]))/T)*RAND_MAX) { tot+=2*a[x]*(a[x]-sum[id[x]]+sum[y]); sum[y]+=a[x],sum[id[x]]-=a[x]; size[y]++,size[id[x]]--; id[x]=y; } T*=v; ans=min(ans,tot); } } int main() { #ifndef ONLINE_JUDGE freopen("bzoj2428.in","r",stdin); freopen("bzoj2428.out","w",stdout); const char LL[]="%I64d\n"; #else const char LL[]="%lld\n"; #endif srand(20020509); n=read(),m=read(); for (int i=1;i<=n;i++) ave+=a[i]=read(); ave/=m; for (int i=1;i<=200;i++) anneal(); printf("%.2lf",sqrt(ans/m)); return 0; }
相关文章推荐
- BZOJ.2428.[HAOI2006]均分数据(随机化贪心/模拟退火)
- BZOJ[2428][HAOI2006]均分数据 模拟退火
- bzoj 2428: [HAOI2006]均分数据 (模拟退火)
- bzoj:2428: [HAOI2006]均分数据 模拟退火
- [BZOJ2428] [HAOI2006]均分数据 && 模拟退火
- [BZOJ 2428][HAOI 2006]均分数据(模拟退火)
- [bzoj2428]:[HAOI2006]均分数据(模拟退火)
- BZOJ2428: [HAOI2006]均分数据 模拟退火
- [BZOJ2428][HAOI2006]均分数据(模拟退火)
- [HAOI2006][BZOJ2428] 均分数据
- bzoj 2428: [HAOI2006]均分数据 随机化
- BZOJ 2428: [HAOI2006]均分数据
- [bzoj2428] [HAOI2006]均分数据
- [bzoj2428]:[HAOI2006]均分数据(爬山算法)
- bzoj 2428: [HAOI2006]均分数据
- 【BZOJ2428】[HAOI2006]均分数据
- BZOJ 2428 [HAOI2006]均分数据 模拟退火
- BZOJ2428:[HAOI2006]均分数据——题解
- BZOJ 2428: [HAOI2006]均分数据
- BZOJ 2428: [HAOI2006]均分数据 模拟退火