P4035 [JSOI2008]球形空间产生器
爬山算法
#include <bits/stdc++.h> #define inf 2333333333333333 #define N 1000010 #define p(a) putchar(a) #define For(i,a,b) for(int i=a;i<=b;++i) using namespace std; int n,m; long double tot,f[20][20],ans[20],d[20],cans[20]; void in(int &x){ int y=1;char c=getchar();x=0; while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();} x*=y; } void o(int x){ if(x<0){p('-');x=-x;} if(x>9)o(x/10); p(x%10+'0'); } void check(){ tot=0; For(i,1,m){ d[i]=0;cans[i]=0; For(j,1,n){ d[i]+=(f[i][j]-ans[j])*(f[i][j]-ans[j]); } tot+=d[i]; } tot/=(long double)m; For(i,1,m){ For(j,1,n){ cans[j]+=(d[i]-tot)*(f[i][j]-ans[j])/tot; } } } signed main(){ in(n);m=n+1; For(i,1,m) For(j,1,n){ cin>>f[i][j]; ans[j]+=f[i][j]; } For(j,1,n) ans[j]/=(long double)m; for(long double t=1000;t>=1e-1;t*=0.9999){ check(); For(j,1,n) ans[j]+=cans[j]*t; } For(j,1,n) printf("%.3Lf ",ans[j]); return 0; }