参照了黑书上的思路,先对方差进行化简,变为求矩阵的平方和最大,然后动态规划。
用G++一直WA,改用C++就过了,百度了下发现G++输出double要用%f。
#include <cstdio> #include <cstring> #include <cmath> #include <iostream> #include <queue> #include <algorithm> using namespace std; int dp[17][9][9][9][9]; int A[9][9]; int sum[9][9][9][9]; const int maxn=1000000000; int main() { int n,i,j,k,l,x,y,a; double ssum=0; scanf("%d",&n); for (i=1;i<=8;i++) for (j=1;j<=8;j++) { scanf("%d",&A[i][j]); ssum+=A[i][j]; } for (i=1;i<=8;i++) for (j=1;j<=8;j++) { for (k=i;k<=8;k++) for (l=j;l<=8;l++) { for (x=i;x<=k;x++) for (y=j;y<=l;y++) sum[i][j][k][l]+=A[x][y]; sum[i][j][k][l]*=sum[i][j][k][l]; dp[1][i][j][k][l]=sum[i][j][k][l]; } } for (k=2;k<=n;k++) { for (i=1;i<=8;i++) for (j=1;j<=8;j++) for (x=i;x<=8;x++) for (y=j;y<=8;y++) { dp[k][i][j][x][y]=maxn; for (a=i;a<x;a++) dp[k][i][j][x][y]=min( min(dp[k-1][a+1][j][x][y]+sum[i][j][a][y], dp[k-1][i][j][a][y]+sum[a+1][j][x][y]),dp[k][i][j][x][y] ); for (a=j;a<y;a++) dp[k][i][j][x][y]=min( min(dp[k-1][i][a+1][x][y]+sum[i][j][x][a], dp[k-1][i][j][x][a]+sum[i][a+1][x][y]),dp[k][i][j][x][y] ); } } double aver=ssum/n; printf("%.3lf\n",sqrt((double)dp[n][1][1][8][8]/n-aver*aver)); }