1 /*
2 思路:
3 我们可以对棋盘进行横向切割和竖向切割
4 s[n][x1][y2][x2][y2]表示:棋盘的左上角坐标是(x1,y1),右下角坐标
5 为(x2,y2) 把这个棋盘分割成 n 一块
6 横向分割:
7 可以在 a处分割 (x1=<a<x2) 比较是 留哪一个继续分割
8 for(a=x1;a<x2;++a)
9 {
10 r=min(r,min(slove(num-1,x1,y1,a,y2)+sum(a+1,y1,x2,y2),//对上边递归继续分割
11 slove(num-1,a+1,y1,x2,y2)+sum(x1,y1,a,y2)));//对下边递归继续分割
12
13 竖向分割:
14 可以在 b 处分割 (y1=<b<y2) 比较是留哪一个
15 for(b=y1;b<y2;++b)
16 {
17 r=min(r,min(slove(num-1,x1,y1,x2,b)+sum(x1,b+1,x2,y2),//对左边继续分割
18 slove(num-1,x1,b+1,x2,y2)+sum(x1,y1,x2,b)));//对右边继续分割
19 }
20 最后的均方差可以化简为:
21 (x1^2 + x2^2 + ....+xn^2)/n-(xba)^2;
22
23
24 rect[i][j]存放的是从(0,0)到 (i,j)这个矩形所有元素的和
25
26 注意:输出时 数学函数 pow(double ,double)
27 */
28 #include<stdio.h>
29 #include<math.h>
30 #include<string.h>
31 #define size 8
32 #define min(a,b) ((a)<(b))?(a):(b)
33
34 int s[15][size+1][size+1][size+1][size+1];
35 int rect[size+1][size+1];
36 int n;
37
38 void inputs()
39 {
40 int i,j;
41 scanf("%d",&n);
42 for(i=1;i<=size;++i)
43 for(j=1;j<=size;++j)
44 scanf("%d",&rect[i][j]);
45 }
46
47 void initial()
48 {
49 int i,j;
50 memset(s,-1,sizeof(s));
51 for(i=0;i<=size;++i)
52 rect[i][0]=rect[0][i]=0;
53 for(i=1;i<=size;++i)
54 for(j=1;j<=size;++j)
55 rect[i][j]+=rect[i-1][j]+rect[i][j-1]-rect[i-1][j-1];
56 }
57
58 int sum(int x1,int y1,int x2,int y2)
59 {
60 int ret = rect[x2][y2]-rect[x1-1][y2]-rect[x2][y1-1]+rect[x1-1][y1-1];
61 return ret*ret;
62 }
63
64 int slove(int num,int x1,int y1,int x2,int y2)
65 {
66 int a,b;
67 int r=1000000000;
68 if(s[num][x1][y1][x2][y2]!=-1)
69 return s[num][x1][y1][x2][y2];
70 else
71 {
72 if(num==1 || x1==x2 || y1==y2)
73 {
74 s[num][x1][y1][x2][y2]=sum(x1,y1,x2,y2);
75 return s[num][x1][y1][x2][y2];
76 }
77 else
78 {
79 for(a=x1;a<x2;++a)
80 {
81 r=min(r,min(slove(num-1,x1,y1,a,y2)+sum(a+1,y1,x2,y2),
82 slove(num-1,a+1,y1,x2,y2)+sum(x1,y1,a,y2)));
83 }
84 for(b=y1;b<y2;++b)
85 {
86 r=min(r,min(slove(num-1,x1,y1,x2,b)+sum(x1,b+1,x2,y2),
87 slove(num-1,x1,b+1,x2,y2)+sum(x1,y1,x2,b)));
88 }
89 s[num][x1][y1][x2][y2]=r;
90 return r;
91 }
92 }
93
94 }
95
96 void print()
97 {
98 double res;
99 res=sqrt((double)slove(n, 1, 1, size, size)/n-pow(sqrt((double)sum(1, 1, size, size))/n, 2.0));
100 printf("%.3f\n", res);
101 }
102
103 int main()
104 {
105 inputs();
106 initial();
107 print();
108 scanf("%d",&n);
109 return 0;
110 }