那个式子可以化简,其实是求xi的最小平方和。 DP来做。 中间因为个很愚蠢的错误送了n次WA。 #include <cmath> #include <iostream> #define _clr(a,b) memset(a,b,sizeof(a)) template<class T> void get_min(T& a,T b) { if(a>b) a=b;} using namespace std; int sum[9][9]; int data[9][9]; void init() { _clr(sum,0); for(int i=1;i<=8;i++) for(int j=1;j<=8;j++) sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+data[i][j]; } int sum_square(int x,int y,int x2,int y2) { int t=sum[x2][y2]-sum[x-1][y2]-sum[x2][y-1]+sum[x-1][y-1]; return t*t; } int dp[16][9][9][9][9]; int run_dp(int n,int x,int y,int x2,int y2) { if(dp[n][x][y][x2][y2]>=0) return dp[n][x][y][x2][y2]; if(n==1) return dp[n][x][y][x2][y2]=sum_square(x,y,x2,y2); int ans=1<<30; for(int t=x;t<x2;t++) { get_min(ans,run_dp(n-1,x,y,t,y2)+sum_square(t+1,y,x2,y2)); get_min(ans,sum_square(x,y,t,y2)+run_dp(n-1,t+1,y,x2,y2)); } for(int t=y;t<y2;t++) { get_min(ans,run_dp(n-1,x,y,x2,t)+sum_square(x,t+1,x2,y2)); get_min(ans,sum_square(x,y,x2,t)+run_dp(n-1,x,t+1,x2,y2)); } return dp[n][x][y][x2][y2]=ans; } int main() { int n; scanf("%d",&n); for(int i=1;i<=8;i++) for(int j=1;j<=8;j++) scanf("%d",&data[i][j]); init(); _clr(dp,-1); double sq_sum=run_dp(n,1,1,8,8); double avg=(double)sum[8][8]/n;//之前没加double,wa了n长时间。因为sum是int,sum/n转换成整型后再转换成double,就会有精度损失。 double ans=sqrt(sq_sum/n-avg*avg); printf("%.3lf/n",ans); return 0; }